I have my simple decorator my_decorator
which decorates the my_func
.
def my_decorator(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
wrapper._decorator_name_ = 'my_decorator'
return wrapper
@my_decorator
def my_func(x):
print('hello %s'%x)
my_func._decorator_name_
'my_decorator'
Till here things work, but I can't see the actual signature of the function.
my_func?
Signature: my_func(*args, **kwargs)
Docstring: <no docstring>
File: ~/<ipython-input-2-e4c91999ef66>
Type: function
If I decorate my decorator with python's decorator.decorator
, I can see the signature of my function but I can't have the new property which I have defined.
import decorator
@decorator.decorator
def my_decorator(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
wrapper._decorator_name_ = 'my_decorator'
return wrapper
@my_decorator
def my_func(x):
print('hello %s'%x)
my_func?
Signature: my_func(x)
Docstring: <no docstring>
File: ~/<ipython-input-8-934f46134434>
Type: function
my_func._decorator_name_
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-10-7e3ef4ebfc8b> in <module>()
----> 1 my_func._decorator_name_
AttributeError: 'function' object has no attribute '_decorator_name_'
How can I have both in python2.7?
For Python 3, using functools.wraps in standard library:
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
wrapper._decorator_name_ = 'my_decorator'
return wrapper
@my_decorator
def my_func(x):
print('hello %s'%x)
print(my_func._decorator_name_)
@decorator.decorator
returns a function which takes another function as input. In your case you want the attribute on the returned function.
For it to work on Python 2.7, you just need some tweak
import decorator
def my_dec2(func):
@decorator.decorator
def my_decorator(func, *args, **kwargs):
print("this was called")
return func(*args, **kwargs)
test = my_decorator(func)
test._decorator_name_ = "my_decorator"
return test
@my_dec2
def my_func(x):
print('hello %s'%x)
my_func(2)
print(my_func._decorator_name_)
And then when you test it works
In [1]: my_func?
Signature: my_func(x)
Docstring: <no docstring>
File: ~/Desktop/payu/projects/decotest/decos.py
Type: function
In [2]: my_func._decorator_name_
Out[2]: 'my_decorator'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With