有时,文本必须更多地阅读,以体现想法的趣味而不是细节。这是其中一种情况。
在链接的页面中,示例2.5、2.6和2.7都应使用一种方法do_your_stuff。(即do_something应更改为do_your_stuff。)
此外,正如Ned Deily指出的那样,A.do_your_stuff必须是一种类方法。
class A(object):
@classmethod
def do_your_stuff(cls):
print 'This is A'
class B(A):
@classmethod
def do_your_stuff(cls):
super(B, cls).do_your_stuff()
B.do_your_stuff()
super(B, cls).do_your_stuff
返回一个绑定方法(请参见脚注2)。由于 cls已作为的第二个参数传递super(),因此它将cls绑定到返回的方法。换句话说,cls被作为第一个参数传递给do_your_stuff()类A的方法。
重申:super(B, cls).do_your_stuff()导致A的do_your_stuff方法cls作为第一个参数传递。为了让这工作,A的
do_your_stuff必须是一个类的方法。链接页面没有提及,但是确实如此。
PS。do_something = classmethod(do_something)是制作类方法的旧方法。新的方法是使用@classmethod装饰器。
请注意,super(B, cls)不能用代替super(cls, cls)。这样做可能导致无限循环。例如,
class A(object):
@classmethod
def do_your_stuff(cls):
print('This is A')
class B(A):
@classmethod
def do_your_stuff(cls):
print('This is B')
super(cls, cls).do_your_stuff()
class C(B):
@classmethod
def do_your_stuff(cls):
print('This is C')
super(cls, cls).do_your_stuff()
C.do_your_stuff()
会提高RuntimeError: maximum recursion depth exceeded while calling a Python object。
如果cls是C,则super(cls, cls)搜索C.mro()后面的类C。
In [161]: C.mro()
Out[161]: [__main__.C, __main__.B, __main__.A, object]
由于该类是B,何时cls是C,super(cls, cls).do_your_stuff() 总是调用B.do_your_stuff。由于super(cls, cls).do_your_stuff()在内部被调用B.do_your_stuff,您最终将B.do_your_stuff陷入无限循环。
在Python3中,添加了0参数形式的super,因此super(B, cls)可以替换为super(),Python3将根据上下文确定super()在的定义中class B应等价于super(B, cls)。
但是在任何情况下super(cls, cls)(或出于类似原因super(type(self), self))都不正确。