是否可以扩展一个应用了装饰器的类?例如:在Python中扩展装饰类
@someDecorator
Class foo(object):
...
...
Class bar(foo):
...
...
理想情况下bar不会受装饰者的影响,但首先我想知道这是否可能。目前,我得到一个非运行时错误:
“类型错误:错误调用元类基地 ()函数的参数1必须是代码的时候,没有str的 ”
有什么建议?
是否可以扩展一个应用了装饰器的类?例如:在Python中扩展装饰类
@someDecorator
Class foo(object):
...
...
Class bar(foo):
...
...
理想情况下bar不会受装饰者的影响,但首先我想知道这是否可能。目前,我得到一个非运行时错误:
“类型错误:错误调用元类基地 ()函数的参数1必须是代码的时候,没有str的 ”
有什么建议?
正如马特所说的,你的装饰器不工作。每当你得到你的装饰正常工作(通过复制做一些测试,甚至imediate测试,并粘贴到一个控制台):
什么的(有效)装饰返回是类“富” - 你不能访问如果使用装饰器语法,装饰器在应用之前是什么。
但是,Python中的装饰器是一种合成糖,它可以用装饰器处理该函数或类来返回以下声明的函数或类。因此,这些是等价的:
@someDecorator
class foo(object):
pass
和
class foo(object):
pass
foo = someDecorator(foo)
因此,你可以简单地通过执行实现应用装饰前扩展一个类的效果:
class foo(object):
pass
class bar(foo):
pass
foo = someDecorator(foo)
是的,只要@someDecorator
实际上正在返回一个类是可能的。类装饰器将类作为它的参数,并且应该几乎总是返回一个类,除非你正在做非常不寻常的事情。
foo
,在这种情况下,将被绑定到任何@someDecorator
返回。
这是装修工会返回其他东西? A str
?
对于任何希望对于所选答案的替代方案,我发现最适合我的方式是在类装饰器中装饰__init__
。例如:
def some_decorator(cls):
def decorate_init(func):
def decorated(*args, **kwargs):
func(*args, **kwargs) # Run __init__
instance = args[0]
# Do whatever you need with the newly constructed instance
return decorated
cls.__init__ = decorated_init(cls.__init__)
return cls
很好的解释,谢谢。我想我现在理解装饰器有点更好了。 – Graham 2010-07-08 15:43:43