代码示例的完成方式使得判断发生了什么有点困难。然而,它相当于:child_methods = [] # a list of all the methods in `Child`
class Parent(object):
def parent_method(self):
print "parent_method() called"
method = child_methods[0]
method(self)
class Child(Parent):
def child_method(self):
print "child_method() called"
# add child_method to child_methods
child_methods.append(Child.child_method)
如您所见,child_methods[0]实际上是函数Child.child_method,它是一个普通函数,而不是一个绑定方法。它与Child的实例无关,这就是为什么您可以并且必须自己传入self。您将从一个Child实例获得一个绑定方法:child_obj = Child()
bound_child_method = child_obj.child_method
如果在实例中找不到属性,Python将查找对象类型中的属性,这一点就不清楚了。例如:# A dummy class to hold attributes
class Foo(object):
pass
Foo.bar = 123 # we're adding an attribute to the type itself
foo1 = Foo()
print foo1.bar # prints 123
foo1.bar = 456 # this `bar` attribute "hides" the one on the type
print foo1.bar # prints 456
foo2 = Foo()
print foo2.bar # prints the 123 from the type again
这就是为什么在您的代码示例中,commands实际上是一个“全局”变量,它只是通过B的一个实例被混乱地访问。(如果只有B的对象或其子对象访问此变量,但查找规则是一个小问题,则这不一定是一个坏做法。)