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
精彩评论