Что я делаю неправильно? Данные хранения инстанцирования объекта Python из предыдущего инстанцирования?

Кто-то может указать мне, что я делаю неправильно или где мое понимание является неправильным?

Мне это походит на код, ниже которого инстанцирует двух объектов, должен иметь отдельные данные для каждого инстанцирования.

class Node:
    def __init__(self, data = []):
        self.data = data

def main():
    a = Node()
    a.data.append('a-data') #only append data to the a instance

    b = Node() #shouldn't this be empty?

    #a data is as expected
    print('number of items in a:', len(a.data))
    for item in a.data:
        print(item)

    #b data includes the data from a
    print('number of items in b:', len(b.data))
    for item in b.data:
        print(item)

if __name__ == '__main__':
    main()

Однако второй объект создается с данными сначала:

>>> 
number of items in a: 1
a-data
number of items in b: 1
a-data
5
задан KobeJohn 1 July 2010 в 21:29
поделиться

3 ответа

Вы не можете использовать мутабельный объект в качестве значения по умолчанию. Все объекты будут использовать один и тот же мутабельный объект.

Сделайте следующее.

class Node:
    def __init__(self, data = None):
        self.data = data if data is not None else []

Когда вы создаете определение класса, он создает объект [] list. Каждый раз, когда вы создаете экземпляр класса, он использует тот же объект list в качестве значения по умолчанию.

8
ответ дан 18 December 2019 в 14:42
поделиться

Проблема в этой строке:

def __init__(self, data = []):

Когда вы пишете data = [] , чтобы установить пустой список как значение по умолчанию для этого аргумента, Python создает список только один раз и использует тот же список каждый раз, когда метод вызывается без явного аргумента data . В вашем случае это происходит при создании как a , так и b , поскольку вы не передаете явный список ни одному из конструкторов, поэтому оба a и b используют тот же объект, что и их список data . Любые изменения, внесенные вами в один, будут отражены в другом.

Чтобы исправить это, я предлагаю заменить первую строку конструктора на

def __init__(self, data=None):
    if data is None:
        data = []
3
ответ дан 18 December 2019 в 14:42
поделиться

Предоставляя значения по умолчанию для функции или метода, вы обычно хотите предоставить неизменяемые объекты. Если вы предоставите пустой список или пустой словарь, вы получите все вызовы этой функции или метода, совместно использующего объект.

Хорошее решение:

def __init__(self, data = None):
    if data == None:
        self.data = []
    else:
        self.data = data
2
ответ дан 18 December 2019 в 14:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: