超出了 Python 类装饰器和最大递归深度

Mic*_*ula 4 python class decorator

我尝试定义类装饰器。我__init__在装饰类中的方法有问题。如果__init__方法调用超出superRuntimeError 最大递归深度,则会引发。

代码示例:

def decorate(cls):
    class NewClass(cls): pass
    return NewClass

@decorate
class Foo(object):
    def __init__(self, *args, **kwargs):
        super(Foo, self).__init__(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

谢谢,米夏?

编辑 1

感谢 Mike Boers 的回答,我意识到正确的问题是我应该怎么做才能使 super(Foo, self) 指向正确的类。

我也有两个限制。我想要调用Foo.__init__方法,但无法更改Foo类定义。

编辑 2

我已经解决了这个问题。我修改了装饰器函数体。我不返回新班级。而不是我包装原始类的方法。

Mik*_*ers 5

请记住,装饰器只是语法糖:

>>> Foo = decorate(Foo)
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,名称 Foo 实际上指的是该类NewClass。在该Foo.__init__方法中,您实际上要求的是 的超级__init__NewClassFoo.__init__(当前正在运行的)。

因此,你Foo.__init__不断地接收自己的__init__调用,最终陷入无限递归。


pet*_*szd 5

您需要覆盖NewClass.__init__以防止递归,因为NewClass.__init__isFoo.__init__并且它一直在调用自己。

def decorate(cls):
    class NewClass(cls):
        def __init__(self):
            pass
    return NewClass
Run Code Online (Sandbox Code Playgroud)

新思路:

不继承它怎么样?也许猴子修补是你的朋友?

def decorate(cls):
    old_do_something = cls.do_something
    def new_do_something(self):
        print "decorated",
        old_do_something(self)

    cls.do_something = new_do_something
    return cls

@decorate
class Foo(object):
    def __init__(self, *args, **kwargs):
        super(Foo, self).__init__(*args, **kwargs)

    def do_something(self):
        print "Foo"

f = Foo()
f.do_something()
Run Code Online (Sandbox Code Playgroud)