在Python中扩展一个装饰类

时间:2010-07-07 22:36:00

标签: python

是否可以扩展应用了装饰器的类?例如:

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

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

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

“TypeError:调用元类库时出错     function()参数1必须是代码,而不是str “

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

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

在这种情况下,

foo将绑定到任何@someDecorator返回。

这装饰师还有其他的东西吗?一个str

答案 1 :(得分: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

答案 2 :(得分:0)

正如马特所说,你的装饰师不能正常工作。每当你让你的装饰工作正常时(进行一些测试,甚至通过复制并粘贴到控制台来进行测试):

(有效)装饰器返回的是你的类“foo” - 如果使用装饰器语法,你无法访问装饰器被应用之前的内容。

然而,Python中的装饰器是一个合成糖,用于通过使用装饰器处理该函数或类所返回的内容来替换以下声明的函数或类。因此,这些是等价的:

@someDecorator
class foo(object):
   pass

class foo(object):
   pass
foo = someDecorator(foo)

因此,您可以通过执行以下操作来实现在应用装饰器之前扩展类的效果:

class foo(object):
   pass
class bar(foo):
   pass

foo = someDecorator(foo)