简体   繁体   English

扩展Python中的修饰类

[英]Extending a decorated class in Python

Is it possible to extend a class which has a decorator applied to it? 是否可以扩展已应用装饰器的类? For example: 例如:

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

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

Ideally bar would not be affected by the decorator, but first I want to find out if this is even possible. 理想情况下,bar不会受到装饰器的影响,但是首先我想弄清楚这是否有可能。 Currently I am getting a non-runtime error: 目前,我收到一个非运行时错误:

"TypeError: Error when calling the metaclass bases function() argument 1 must be code, not str " “ TypeError:调用元类基础function()参数1时出错,必须是代码,而不是str”

Any suggestions? 有什么建议么?

Yes it is possible, as long as @someDecorator is actually returning a class. 是的,只要@someDecorator实际上正在返回一个类,就可以。 A class decorator takes a class as its argument, and should almost always return a class, unless you are doing something very unusual. 类装饰器将类作为其参数,并且几乎应该总是返回一个类,除非您做的非常不寻常。

foo , in this case, will be bound to whatever @someDecorator returns. 在这种情况下, foo将绑定到@someDecorator返回的任何@someDecorator

Is this decorator returning something else? 这个装饰器还会返回其他东西吗? A str ? 一个str

For anyone looking for an alternative to the chosen answer, I found best way for me was to decorate __init__ inside the class decorator. 对于寻求替代所选答案的任何人,我发现对我来说最好的方法是在类装饰器中装饰__init__ So for example: 因此,例如:

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

As Matt put it, your decorator is not working. 正如Matt所说,您的装饰器无法正常工作。 Whenever you get your decorator to work properly (make some tests, even imediate tests by copying and paste to a console): 每当您使装饰器正常工作时(进行一些测试,甚至通过复制并粘贴到控制台进行即时测试):

What the (valid) decorator returns is your class "foo" - you can't access what it was before the decorator being applied if you use the decorator syntax. (有效的)装饰器返回的您的类“ foo”-如果使用装饰器语法,则无法访问应用装饰器之前的状态。

However, decorators in Python are a syntatic sugar to replace the following declared function or class with what is returned by processing that function or class with the decorator. 但是,Python中的装饰器是一种语法糖,可以通过用装饰器处理该函数或类所返回的内容来替换以下声明的函数或类。 Thus, these are equivalent: 因此,这些等效:

@someDecorator
class foo(object):
   pass

and

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

Therefore, you can achieve the effect of extending a class before applying the decorator simply by doing: 因此,只需执行以下操作,即可在应用装饰器之前达到扩展类的效果:

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

foo = someDecorator(foo)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM