I'm trying to get the reference to the originally decorated function from within a decorator. How can this be done?
import inspect
from functools import wraps
def test_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# the closest I could get to getting the original function:
# it prints the frame from which the function was called.
current_frame = inspect.currentframe()
outer_frames = inspect.getouterframes(current_frame)
print(outer_frames[-1].frame)
return func(*args, **kwargs)
return wrapper
@test_decorator
@test_decorator
@test_decorator
def test_func(a, b, c):
print("func")
test_func(1,2,3)
The 'originally decorated function' in this context would be test_func
, since it's the target function we're decorating. I've looked through the inspect
module, the closest I could get is by getting the first frame on the stack, but it doesn't help much.
Maybe, there is a solution already in stdlib?
This:
https://github.com/micheles/decorator
import inspect
from decorator import decorator
@decorator
def test_decorator(func, *args, **kwargs):
print(inspect.getfullargspec(func))
return func(*args, **kwargs)
@test_decorator
@test_decorator
@test_decorator
def test_func(a, b, c):
print("func")
test_func(1,2,3)
Now from within each test_decorator
it prints:
FullArgSpec(args=['a', 'b', 'c'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})
Bless this man who wrote the module, the guy is a legend.