我想要的是创建一个类装饰器来装饰类并在子类上工作。
想象一下这个课程:
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
你知道是否可以这样做吗?怎么样?
感谢!!!
答案 0 :(得分: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)
这对我有用!!如果我打错了,我会提前道歉。