【问题标题】:How to decorate a parent class and make child classes use it? python如何装饰父类并让子类使用它? Python
【发布时间】:2014-03-02 09:32:07
【问题描述】:

我想要的是创建一个类装饰器来装饰一个类并在子类上工作。

想象一下这个类:

class CustomBaseTest(TransactionTestCase):
    def __init__(self, *args, **kwargs):
        ...

    def more_custom_helpers(self):
        ...

和真正的测试:

class FooTest(CustomBaseTest):
    def decorate_this_foo_is_ok(self):
        ....

    def decorate_this_fails(self):
        ...

我想要的是在CustomBaseTest 中使用一个装饰器,它可以找到所有以“decoratte_this_”开头的方法并在前后执行自定义代码。我已经有了装饰器,像这样:

def class_decorator(klass):
    is_method_test = lambda m: not m.startswith('_') and m.startswith('decorate_this_') and isinstance(getattr(klass, m), MethodType)
    test_methods = filter(is_method_test, dir(klass))

    for method_name in test_methods:
        class_method = getattr(klass, method_name)

        def helper(mname, method):
            @wraps(method)
            ... some logic here
            retval = method(*a, **kw)
            ... more logic here
            return retval
        return wrapper

        fn = MethodType(helper(method_name, class_method), None, klass)
        setattr(klass, method_name, fn)
    return klass

你知道是否可以这样做吗?以及如何?

谢谢!!!

【问题讨论】:

  • 1) 尝试设置类的__metaclass__ 属性。 2)修改基类的__new__方法。
  • 类装饰器仅适用于它们装饰的实际类。正如 Joel Cornett 所说,您可以使用元类。谷歌搜索有关如何使用元类的信息。
  • 元类是要走的路!!!多谢你们!!!我解决了我的问题!!!! :)
  • @pahko,您应该发布您的解决方案作为答案。

标签: python python-decorators


【解决方案1】:

感谢@Markku 和@BrenBarn。

这是解决方案。

首先我们有一个简单的装饰器:

from functools import wraps
def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # do some stuff
        retval = func(*args, **kwargs)
        # do more stuff
        return retval
    return wrapper

和元类:

class ProfileMetaByClass(type):
    def __init__(cls, name, bases, dct):
        for method_name, method in dct.items():
            if method_name.startswith('decorate_this_'):
                setattr(cls, key, my_decorator(value))
        type.__init__(cls, name, bases, dct)

这对我有用!如果我打错了,我提前道歉。

【讨论】:

    猜你喜欢
    • 2011-11-20
    • 2022-01-16
    • 2020-11-25
    • 2011-03-26
    • 2017-02-21
    • 2021-07-16
    • 2021-03-15
    • 1970-01-01
    • 2019-08-08
    相关资源
    最近更新 更多