2010-07-07 77 views
1

是否可以扩展一个应用了装饰器的类?例如:在Python中扩展装饰类

@someDecorator 
Class foo(object): 
    ... 
    ... 

Class bar(foo): 
    ... 
    ... 

理想情况下bar不会受装饰者的影响,但首先我想知道这是否可能。目前,我得到一个非运行时错误:

“类型错误:错误调用元类基地 ()函数的参数1必须是代码的时候,没有str的 ”

有什么建议?

回答

0

正如马特所说的,你的装饰器不工作。每当你得到你的装饰正常工作(通过复制做一些测试,甚至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) 
+0

很好的解释,谢谢。我想我现在理解装饰器有点更好了。 – Graham 2010-07-08 15:43:43

2

是的,只要@someDecorator实际上正在返回一个类是可能的。类装饰器将类作为它的参数,并且应该几乎总是返回一个类,除非你正在做非常不寻常的事情。

foo,在这种情况下,将被绑定到任何@someDecorator返回。

这是装修工会返回其他东西? A str

1

对于任何希望对于所选答案的替代方案,我发现最适合我的方式是在类装饰器中装饰__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