Изменить функцию в декораторе
Я думал о создании декоратора с целью повышения производительности. Декоратор, который изменяет исходный код функции, которую он декорирует, и возвращает измененную функцию.
Обдумывая это, я подумал, что если бы я мог просто получить исходный код функции, я мог бы сделать это. Но возможно ли получить доступ к исходному коду функции внутри декоратора? Если у меня есть декоратор, как это:
import inspect
def decorate(f):
exec(inspect.getsource(f))
return eval(f.__name__)
@decorate
def test():
return 1
Я получаю OSError:
OSError: could not get source code
Это, кажется, потому чтоtest
не полностью сформирован, прежде чем он передается вdecorate
, Тем не менее, это работает:
import inspect
def decorate(f):
exec(inspect.getsource(f))
return eval(f.__name__)
def test():
return 1
test = decorate(test)
Это просто не имеет этого декораторского таланта к этому, все же. Кажется, это возможно, потому чтоf.__code__
является определены.
При дальнейшей проверке выясняется, что это происходит только тогда, когда яinspect.getsource(f)
вexec
, В противном случае кажется, что я могу получить исходный код.
Как грубый набросок первого, что у меня на уме, я думаю о хвостовой рекурсии. Я написал этот декоратор, который, к сожалению, медленный и требует очень специфического стиля написания функции для оформления:
def tail_recurse(acc_default):
def decorate(f):
def wrapper(*args, acc=acc_default):
args = args + (acc,)
while True:
return_type, *rargs = f(*args)
if return_type is None:
return rargs[-1]
args = rargs
return wrapper
return decorate
По сути, я думаю сделать что-то столь же простое, как заменить тело функции на:
while True:
__body__
update_args