#python #decorator #python-decorators
Вопрос:
Я пытаюсь получить ссылку на первоначально оформленную функцию из декоратора. Как это можно сделать?
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)
«Первоначально оформленная функция» в этом контексте будет такой test_func
, поскольку это целевая функция, которую мы украшаем. Я просмотрел inspect
модуль, самое близкое, что я мог получить, — это получить первый кадр в стеке, но это не сильно помогает.
Может быть, в stdlib уже есть решение?
Комментарии:
1. Разве это не просто
func
в вашем случае? Попробуйте добавитьprint("It's me:", func)
подdef wrapper(...):
2. @Рафаэль-ВО нет, к сожалению, это не так. Декораторы складываются стопкой, но друг на друге. Очевидно, что единственный, кто видит настоящее
func
, — последний@test_decorator
.3. @Rafael-WO на самом деле это проблема, которую я пытаюсь решить. Чтобы увидеть исходную функцию от любого декоратора в стеке.
Ответ №1:
Этот:
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)
Теперь изнутри каждого test_decorator
он печатает:
FullArgSpec(args=['a', 'b', 'c'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})
Благослови господь этого человека, написавшего модуль, этот парень-легенда.