Mic*_*ula 4 python class decorator
我尝试定义类装饰器。我__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)
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谢谢,米夏?
编辑 1
感谢 Mike Boers 的回答,我意识到正确的问题是我应该怎么做才能使 super(Foo, self) 指向正确的类。
我也有两个限制。我想要调用Foo.__init__方法,但无法更改Foo类定义。
编辑 2
我已经解决了这个问题。我修改了装饰器函数体。我不返回新班级。而不是我包装原始类的方法。
请记住,装饰器只是语法糖:
>>> Foo = decorate(Foo)
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下,名称 Foo 实际上指的是该类NewClass。在该Foo.__init__方法中,您实际上要求的是 的超级__init__,NewClass即Foo.__init__(当前正在运行的)。
因此,你Foo.__init__不断地接收自己的__init__调用,最终陷入无限递归。
您需要覆盖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)