有时,必须更多地阅读文本以获得想法的味道,而不是细节。这是其中一种情况。
在链接页面中,示例 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's
do_your_stuff必须是一个类方法。链接页面没有提到这一点,但确实如此。
PS。do_something = classmethod(do_something)是制作类方法的旧方法。新的(er)方法是使用 @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(B, cls).do_your_stuff() # CORRECT
super(cls, cls).do_your_stuff() # WRONG
class C(B):
@classmethod
def do_your_stuff(cls):
print('This is C')
# super(C, cls).do_your_stuff() # CORRECT
super(cls, cls).do_your_stuff() # WRONG
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()被调用 inside 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))都不正确。