开发者

Inheritance + Class members

I'm starting with Python and encountered this weird behaviour (atleast for me):

class Parent:
    myStr = ""
    myI开发者_如何转开发nt = 0
    myDict = {}
    ....

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

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

Based on my understanding, instances of both ChildA and ChildB should have their own dictionaries. But it turns out that they "share" the dictionary. To fix it, I need to set self.myDict={} in the parent's constructor. On the other hand, myStr and myInt appear to have their intended values. Why does this happen?


myDict is class-level, so when Python looks at the instance and doesn't find it, it searches up the inheritence tree until it does. If you re-bind the name myDict anywhere in the instance, then the instance will have its own version.

This behavior is easy to see when using mutable objects such as dict, list, etc, but more difficult to observe with immutable objects such as str, int, tuple, etc, because in order to 'change' the value of an immutable you have to rebind the name -- something like this:

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


This happens because names bound at the class level belong to the class, not any instance. Therefore, all myDict are the same dict. Since dict instances are mutable, changes you make via one class/instance reference show up in all. Strings and numbers are immutable, so they are rebound instead when assigned via a subclass or instance.


This happens because setting myDict at the class level binds it to the class and not instances of the class (that is, all instances will share the same myDict).


The key to the issue is as Ignacio pointed out, mutable vs. immutable. Here's a link to a lengthy explanation complete with ASCII diagrams:

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜