Python - Почему это происходит? - PullRequest
0 голосов
/ 28 июня 2011

Я новичок в Python и заметил кое-что, что, по-моему, является ошибкой.

Редактировать 2011-09-30: Забудьте об этом.Теперь я знаю, что созданные атрибуты являются статическими и совместно используются экземплярами.Надеюсь, этот поток поможет другим новичкам в Python в той же ситуации, что и моя.

Рассмотрим следующий код:

class test():

    dictionary1 = {}
    list1 = []

    def method1(self):
        self.dictionary1.update({'1': 'unique entry'})
        self.list1 = ['unique list entry']

t=test()

print 'dictionary1 value:', t.dictionary1
print 'list1 value:', t.list1
t.method1()
print 'dictionary1 new value:', t.dictionary1
print 'list1 new value:', t.list1

t2=test()
print 'dictionary1 value:', t2.dictionary1, " -- error -- I just instantiated the class. The correct value would be {}"
print 'list1 value:', t.list1
t2.method1()
print 'dictionary1 new value:', t.dictionary1
print 'list1 new value:', t.list1

Теперь вопрос:

Почему в строке 19 выполненокод показывает: {'1': 'unique entry'}.Я полагаю, что это будет: {} Обратите внимание, что список имеет правильное значение: [] (пустой список в строке 20)

Using Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2

Извините, не очень хороший английский.Из Бразилии.

Редактировать 2011-09-30: Забудьте об этом.Теперь я знаю, что созданные атрибуты являются статическими и совместно используются экземплярами.Надеюсь, этот поток поможет другим новичкам в Python в той же ситуации, что и моя.

Ответы [ 3 ]

14 голосов
/ 28 июня 2011

Все ваши экземпляры класса test используют один и тот же словарь и список. Правильный способ инициализации членов будет:

class Test():
    def __init__(self):
        self.dictionary1 = {}
        self.list1 = []

Атрибуты, присвоенные непосредственно в теле класса, будут оценены один раз, а затем распределены между всеми экземплярами. Поскольку метод __init__ запускается один раз для каждого экземпляра, для каждого экземпляра будет создан новый список и словарь.

7 голосов
/ 28 июня 2011

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

Вместо этого инициализируйте переменные-члены объекта в конструкторе:

class test(object):
    def __init__(self):
        self.dictionary1 = {}
    def method1(self):
        self.dictionary1.update({'1': 'unique entry'})
5 голосов
/ 28 июня 2011

Чтобы добавить к другим ответам, причина, по которой вы видите различное поведение для dict и list: когда вы пишете self.dictionary1.update({'1': 'unique entry'}), вы изменяете содержимое self.dictionary1, но оно все равно dict объект.Когда вы пишете self.list1 = ['unique list entry'], вы заменяете self.list1 новым list объектом.Вы получите то же поведение, что и с dict, выполнив: self.list1.append('unique list entry').

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...