【问题标题】:Python class decorator and maximum recursion depth exceeded超出 Python 类装饰器和最大递归深度
【发布时间】:2011-03-01 15:52:07
【问题描述】:

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

代码示例:

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

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

我做错了什么?

谢谢,米哈乌

编辑 1

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

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

编辑 2

我已经解决了这个问题。我修改装饰器功能体。我不返回新课程。而不是我包装原始类的方法。

【问题讨论】:

标签: python class decorator


【解决方案1】:

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

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

新想法:

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

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()

【讨论】:

  • 好的,但我想执行 Foo.__init__ 方法。我也无法编辑 Foo 类定义。
  • 希望“不是子类”是一个单独的答案,所以我可以在修改实际类(在太多情况下不起作用)之上 +1。
【解决方案2】:

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

>>> Foo = decorate(Foo)

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

因此,您的Foo.__init__ 不断收到自己的__init__ 来调用,并且您最终陷入无限递归。

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2020-07-13
    • 2021-02-07
    • 2017-03-18
    • 2015-04-15
    • 1970-01-01
    相关资源
    最近更新 更多