有时,文本必须更多地阅读,以体现想法的趣味而不是细节。这是其中一种情况。
在链接的页面中,示例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)
)都不正确。