简体   繁体   English

将装饰器添加到继承类的方法中?

[英]Add decorator to a method from inherited class?

I want to inherit from class just to add decorators to its methods. 我想从类继承,只是将装饰器添加到其方法。

Is there a shortcut to do this without redefining each base class method? 有没有在不重新定义每个基类方法的情况下执行此操作的捷径?

Sure, you can do this dynamically. 当然,您可以动态地执行此操作。 Suppose you have some class: 假设您有一些课程:

>>> class Foo:
...    def bar(self): print('bar')
...    def baz(self): print('baz')
...

And a decorator: 还有一个装饰器:

>>> def deco(f):
...    def wrapper(self):
...       print('decorated')
...       return f(self)
...    return wrapper
...

Then simply inherit: 然后简单地继承:

>>> class Foo2(Foo):
...     pass
...

Then loop over your original class, and apply the decorator to your new child-class: 然后遍历您的原始类,并将装饰器应用于新的子类:

>>> for name, attr in vars(Foo).items():
...     if callable(attr):
...         setattr(Foo2, name, deco(attr))
...

So... 所以...

>>> x = Foo2()
>>> x.bar()
decorated
bar
>>> x.baz()
decorated
baz

Now, using if callable(attr) might not be restrictive enough. 现在,使用if callable(attr)可能不够严格。 You might want to ignore "dunder" methods, so instead: 您可能要忽略“ dunder”方法,因此:

for name, attr in vars(Foo):
    if callable(attr) and not name.startswith('__'):
        setattr(Foo2, name, attr)

might be more appropriate. 可能更合适。 Depends on your use-case. 取决于您的用例。

And just for fun, here we can also use the type constructor: 只是为了好玩,在这里我们还可以使用type构造函数:

In [17]: class Foo:
    ...:     def bar(self): print('bar')
    ...:     def baz(self): print('baz')
    ...:

In [18]: def deco(f):
    ...:     def wrapper(self):
    ...:         print('decorated')
    ...:         return f(self)
    ...:     return wrapper
    ...:

In [19]: Foo3 = type(
    ...:     'Foo3',
    ...:     (Foo,),
    ...:     {name:deco(attr) for name, attr in vars(Foo).items() if callable(attr)}
    ...: )

In [20]: y = Foo3()

In [21]: y.bar()
decorated
bar

In [22]: y.baz()
decorated
baz

You can use a class decorator to encapsulate the whole work 您可以使用类装饰器来封装整个工作

Example code: 示例代码:

def deco(func):
    """Function decorator"""
    def inner(*args, **kwargs):
        print("decorated version")
        return func(*args, **kwargs)
    return inner

def decoclass(decorator):
    """Class decorator: decorates public methods with decorator"""
    def outer(cls):
        class inner(cls):
            pass
        for name in dir(cls):
            if not name.startswith("_"):     # ignore hidden and private members
                # print("decorating", name)  # uncomment for tests
                attr = getattr(inner, name)
                setattr(inner, name, decorator(attr))
        return inner
    return outer

class Foo:
    """Sample class""
    def foo(self):
        return "foo in Foo"

You can then use it: 然后可以使用它:

>>> @decoclass(deco)
class Foo2(Foo):
    pass

>>> f = Foo2()
>>> f.foo()
decorated version
'foo in Foo'

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

相关问题 使用从父类继承的方法作为子类方法的装饰器 - Use inherited method from parent class as decorator on child classes method 从子类继承的python3装饰器方法 - python3 decorator method inherited from child class 将装饰器添加到库中的方法 class - Add decorator to method from library class 如何在不复制整个方法的情况下在Python中向继承的方法添加装饰器? - How to add a decorator to inherited method in Python without copying whole method? 如何在 DRF 的 urls.py 文件中访问从 APIView Class 继承的视图的 @action 装饰器装饰的方法? - How to Access method decorated with @action decorator of a view inherited from APIView Class in urls.py file in DRF? 使用装饰器动态地向类添加方法 - add method to a class dynamically with decorator 如何在类中声明装饰器,以装饰已经装饰的继承方法? - How to declare decorator inside a class, to decorate an already decorated, inherited method? 在python中的现有内置类方法中添加装饰器 - Add a decorator to existing builtin class method in python 在继承的类中重写抽象类的装饰器 - Overriding the decorator of an abstract class in the inherited class 使用装饰器将 class 外部的方法包装在 Python 中 - Wrapping a method from outside the class in Python with decorator
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM