Наследование + Члены класса - PullRequest
0 голосов
/ 14 сентября 2011

Я начинаю с Python и столкнулся со странным поведением (по крайней мере для меня):

class Parent:
    myStr = ""
    myInt = 0
    myDict = {}
    ....

class ChildA:
    ...
    def ...():
        self.myDict.<something>(...)
        print self.myStr
    ...

class ChildB:
    ...
    def ...():
        self.myDict.<something>(...)
        print self.myStr
    ...

Насколько я понимаю, экземпляры ChildA и ChildB должны иметь свои собственные словари.Но оказывается, что они «делятся» со словарем.Чтобы это исправить, мне нужно установить self.myDict = {} в конструкторе родителя.С другой стороны, myStr и myInt, кажется, имеют свои предполагаемые значения.Почему это происходит?

Ответы [ 4 ]

3 голосов
/ 14 сентября 2011

myDict на уровне класса, поэтому, когда Python просматривает экземпляр и не находит его, он ищет дерево наследования, пока не обнаружит. Если вы перепривязываете имя myDict в любом месте экземпляра, то экземпляр будет иметь свою собственную версию.

Это поведение легко увидеть при использовании изменяемых объектов, таких как dict, list и т. Д., Но его сложнее наблюдать с неизменяемыми объектами, такими как str, int, tuple и т. Д., Поскольку чтобы «изменить» значение неизменяемого, вам нужно привязать имя - что-то вроде этого:

class Foo(object):
    collection = list()
    number = 9
    def change_collection(self, new_member):
        self.collection.append(new_member)
    def change_number(self, new_number):
        self.number = new_number

a = Foo()
b = Foo()
a.change_collection('howdy!')
b.change_number(11)
print a.collection, b.collection     # ['howdy!]  ['howdy!']
print a.number, b.number             # 9  11
print a.collection is b.collection   # True
print a.number is b.number           # False
3 голосов
/ 14 сентября 2011

Это происходит потому, что имена, связанные на уровне класса, принадлежат классу, а не любому экземпляру.Следовательно, все myDict являются одним и тем же диктом.Поскольку экземпляры dict изменчивы, изменения, которые вы вносите с помощью одной ссылки на класс / экземпляр, отображаются во всех.Строки и числа являются неизменяемыми, поэтому вместо этого они восстанавливаются при назначении через подкласс или экземпляр.

2 голосов
/ 14 сентября 2011

Это происходит потому, что установка myDict на уровне class связывает его с классом, а not экземпляры класса (то есть все экземпляры будут иметь одинаковые myDict ).

0 голосов
/ 14 сентября 2011

Ключ к проблеме, как указал Игнасио, изменчивый и неизменный. Вот ссылка на длинное объяснение с диаграммами ASCII:

http://mail.python.org/pipermail/tutor/2001-February/003787.html

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