Я думал о создании декоратора с целью повышения производительности. Декоратор, который изменяет исходный код функции, которую он украшает, и возвращает измененную функцию.
Подумав об этом, я подумал, что если бы я мог просто получить исходный код функции, я мог бы это сделать. Но возможно ли получить доступ к исходному коду функции внутри декоратора? Если у меня есть декоратор:
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