1

In the following code the methods(print_a and print_b) of class Test, has been decorated by the two different decorators.

How can I determine that the given method(let say print_a), is decorated with some specific decorator (decorator1) at the runtime?

The easy solution is to change the name of the wrapper function, i.e. changing the wrapper to wrapper1 and wrapper2 in the decorator method, but the problem with that is I don't have control over that part of the code.

Does python have any reflection API like Java, and could that help me here ?

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') 

2 Answers 2

3

Since the decorator function is executed at decoration time, it is difficult to get the name. You can solve your problem with an additional decorator. The decorator annotator writes into a property of the function and you can read this name inside of the decorated function:

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 
Sign up to request clarification or add additional context in comments.

3 Comments

I have no access to decorator code but I think I need to request the maintainer to add this.
If you adapt my example this shouldn't be necessary, and it will work for decorators where you can't request the maintainer.
gotcha, this is new decorator which is calling actual decorator
1

Python decorators are more about transforming functions than about acting as simple metadata labels, as one often does with Java annotations. So to do this, I'd have the decorator set a property on the function it is wrapping (or perhaps wrap it in a callable of a particular type):

def my_decorator1(func): def wrapper(*args, **kwargs): print('I am decorated:1') func(*args, **kwargs) wrapper.decorator_name = 'my_decorator1' return wrapper 

Then:

print(Test.print_a.decorator_name) 

Alternatively, in Python 3.3+ you can use PEP 3155's __qualname__ to identify the decorator.

1 Comment

The OP said he had no access to the decorator definitions.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.