The way the code sample is done makes it a little harder to tell what's going on. However, it's equivalent to:
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)
As you can see, child_methods[0]
will actually be the function Child.child_method
, which is a plain function, and not a bound method. It's not associated with an instance of Child
, which is why you can and have to pass in the self
yourself. You'd get a bound method from a Child
instance with:
child_obj = Child()
bound_child_method = child_obj.child_method
This is made unclear by the fact Python will look up attributes in the type of an object if they're not found in the instance. For example:
# 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
This is why, in your code sample, commands
is really a "global" variable, it just gets accessed confusingly through an instance of B
. (This is not necessarily a bad practice if only objects of B
or its children access this variable, but the lookup rules are a minor gotcha.)