我在装饰类中看到无限递归:
def my_decorator():
def class_decorator(cls):
class NewClass(cls):
@classmethod
def func(cls):
print "decorator"
super(NewClass, cls).func()
return NewClass
return class_decorator
class B(object):
@classmethod
def func(cls):
print "Root"
@my_decorator()
class A(B):
@classmethod
def func(cls):
print "func"
super(A, cls).func()
x = A()
x.func()
输出:
decorator
func
func
func
func
... <lots of 'func'> ...
lots of these:
File "test.py", line 22, in func
super(A, cls).func()
File "test.py", line 22, in func
super(A, cls).func()
File "test.py", line 22, in func
super(A, cls).func()
RuntimeError: maximum recursion depth exceeded while calling a Python object
没有装饰器,它返回:
func
Root
......正如所料。
发生了什么?
答案 0 :(得分:2)
在您装饰原始A
后,相当于:
A = my_decorator()(A)
名称A
是指新创建的NewClass
,它还会继承原始A
,不原始A
。因此super(A, cls).func
始终解析为super(NewClass, cls).func
,即A.func
。
展开装饰器并将结果分配给不同的名称,您将获得正确的行为:
X = my_decorator()(A)
x = X()
x.func()
给出:
decorator
func
Root
答案 1 :(得分:0)
这样的代码:
@my_decorator()
class A(B):
# ...
在语义上与:
相同A = my_decorator(A)
(根据PEP 3129)
这意味着名称为A
的符号,通常会将Type值设置为“A类”,实际上重新定义是从my_decorator
返回的任何内容,类型为NewClass
。
所以在你打电话的时候
super(A, cls).func()
A
实际上是指NewClass
(和cls
一样),导致调用相同的方法。