python - 装饰器中的无限递归(类似乎是从自身继承的)

标签 python python-2.7 recursion

我在装饰类中看到无限递归:

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

...正如预期的那样。

这是怎么回事?

最佳答案

在你装饰了原来的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

关于python - 装饰器中的无限递归(类似乎是从自身继承的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32462558/

相关文章:

python:检查 XSD xml 模式

python - 如何在 Windows 上使用信号退出功能?

python 2.7 re.MULTILINE 问题

java - 在 Java 中使用递归打印素数

javascript - 如何使用递归迭代包含数组、对象、k-v 对的 Json 响应?

python - python 上的简单正则表达式

python - 使用脚本参数在 Snakemake 中指定 Python 版本

python - PySide:为什么在另一个 QmainWIndow(Main) 中触发 QAction 时 QMainWindow flask 并消失

python - 使用 Python 生成私有(private)/公共(public) SSH key

python - 如何使用递归在 BeautifulSoup 中进行抓取?