在以下代码中,类print_a
的方法(print_b
和Test
)已由两个不同的装饰器修饰。
如何确定给定方法(比如说print_a
)是否在运行时装饰了一些特定的装饰器(decorator1
)?
简单的解决方案是更改包装函数的名称,即在装饰器方法中将wrapper
更改为wrapper1
和wrapper2
,但问题是我不知道t可以控制代码的那一部分。
python是否有像Java这样的反射API,这对我有帮助吗?
def my_decorator1(func):
def wrapper(*args, **kwargs):
print('I am decorated:1')
func(*args, **kwargs)
return wrapper
def my_decorator2(func):
def wrapper(*args, **kwargs):
print('I am decorated:2')
func(*args, **kwargs)
return wrapper
class Test():
def __init__(self, a=None, b=None):
self.a = a
self.b = b
@my_decorator1
def print_a(self):
print('Value of a is {}'.format(self.a))
@my_decorator2
def print_b(self):
print('Value of b is {}'.format(self.b))
if __name__ == '__main__':
d = Test.__dict__
f1 = d.get('print_a')
f2 = d.get('print_b')
答案 0 :(得分:3)
由于装饰器功能在装饰时执行,因此很难获得名称。您可以使用其他装饰器来解决您的问题。装饰器annotator
写入函数的属性,您可以在装饰函数中读取此名称:
def annotator(decorator):
def wrapper(f):
g = decorator(f)
g.decorator = decorator.__name__
return g
return wrapper
@annotator(my_decorator1)
def x():
print x.decorator
答案 1 :(得分:1)
Python装饰器更多的是关于转换函数而不是简单的元数据标签,就像Java注释一样。所以为了做到这一点,我让装饰器在它正在包装的函数上设置一个属性(或者可能将它包装在特定类型的可调用函数中):
def my_decorator1(func):
def wrapper(*args, **kwargs):
print('I am decorated:1')
func(*args, **kwargs)
wrapper.decorator_name = 'my_decorator1'
return wrapper
然后:
print(Test.print_a.decorator_name)
或者,在Python 3.3+中,您可以使用PEP 3155' __qualname__
来识别装饰器。