我为类方法
编写了一个装饰器def decor(method):
def wrapped(self, *args, **kwargs):
return method(self, *args, **kwargs)
# [*]
return wrapped
我想用这个:
class A(metaclass=mymetaclass):
@decor
def meth(self):
pass
如何在装饰器中添加方法/变量到具有装饰方法的类?我需要在[*]
附近做。
在内部包裹我可以写self.__class__
,但在这里做什么?
答案 0 :(得分:5)
我无法想象一种满足这种要求的方法,因为decor
函数只接收一个对包含类一无所知的函数对象。
我能想象的唯一解决方法是使用参数化装饰器并将其传递给正在装饰的类
def decor(cls):
def wrapper(method):
def wrapped(self, *args, **kwargs):
return self.method(*args, **kwargs)
print method # only a function object here
return wrapped
print cls # here we get the class and can manipulate it
return wrapper
class A
@decor(A)
def method(self):
pass
或者,您可以自己修饰类:
def cdecor(cls):
print 'Decorating', cls # here we get the class and can manipulate it
return cls
@cdecor
class B:
def meth(self):
pass
给出:
Decorating __main__.B
答案 1 :(得分:0)
根据这一回应,它看起来似乎不可能直接成为可能:
Get Python function's owning class from decorator
你可以做的是为你的班级提供装饰,类似的东西:
class InsertMethod(object):
def __init__(self, methodToInsert):
self.methodToInsert = methodToInsert
def __call__(self, classObject):
def wrapper(*args, **kwargs):
setattr(classObject, self.methodToInsert.__name__, self.methodToInsert)
return classObject(*args, **kwargs)
return wrapper
def IWillBeInserted(self):
print "Success"
@InsertMethod(IWillBeInserted)
class Something(object):
def __init__(self):
pass
def action(self):
self.IWillBeInserted()
a = Something()
a.action()
答案 2 :(得分:0)
实际上,你可以装饰这个类本身:
def class_decorator(class_):
class_.attribute = 'value'
class_.method = decorate(class_.method)
return class_
@class_decorator
class MyClass:
def method(self):
pass
答案 3 :(得分:0)
我聚会晚了一点,但是迟到总比不到好吗? :)
我们可以通过用一个装饰器(它本身是一个类对象,例如B
)装饰我们的类方法,然后挂接到Python调用B.__get__
的那一刻来获取该方法来做到这一点。在将通过所有者类和该类的新生成的实例传递的__get__
调用中,您可以选择将方法/变量插入原始所有者类或新定义的实例中。 / p>
class B(object):
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
return self.f(*args, **kwargs)
def __get__(self, instance, owner):
instance.inserted = True
# owner.inserted = True
def wrapper(*args, **kwargs):
return self(instance, *args, **kwargs)
return wrapper
class A:
@B
def method(self):
pass
if __name__ == "__main__":
a = A()
a.method()
b = A()
print(hasattr(a, 'inserted'))
print(hasattr(b, 'inserted'))
在此示例中,我们用def method(self)
包装@B
。如所写,插入的属性inserted
将仅在a
对象中保留,因为它被应用于实例。如果如图所示创建第二个对象b
,则不包含inserted
属性。 IE,hasattr(a, 'inserted')
打印True
,而hasattr(b, 'inserted')
打印False
。但是,如果我们将inserted
应用于owner
类(如注释行所示),则插入的属性将持久存在于所有将来的A()
对象中。 IE hasattr(a, 'inserted')
打印True
,而hasattr(b, 'inserted')
打印True
,因为b
是在调用a.method()
之后创建的。
答案 4 :(得分:0)
您似乎只是想装饰一个类函数,而不是@classmethod。这是我想在函数返回成功结果时调用类保存函数的一种简单方法:
def save_on_success(func):
""" A decorator that calls a class object's save method when successful """
def inner(self, *args, **kwargs):
result = func(self, *args, **kwargs)
if result:
self.save()
return result
return inner
以下是使用方式的示例:
class Test:
def save(self):
print('saving')
@save_on_success
def test(self, var, result=True):
print('testing, var={}'.format(var))
return result
进行测试以确保其可以正常工作:
>>> x = Test()
>>> print(x.test('test True (should save)', result=True))
testing, var=test True (should save)
saving
True
>>> print(x.test('test False (should not save)', result=False))
testing, var=test False (should not save)
False