Modificar função no decorador
Eu estava pensando em fazer um decorador com o objetivo de aumentar o desempenho. Um decorador que modifica o código fonte da função que decora e retorna a função modificada.
Enquanto pensava sobre isso, imaginei que, se pudesse obter o código fonte da função, poderia fazê-lo. Mas é possível acessar o código fonte de uma função dentro de um decorador? Se eu tiver um decorador como este:
import inspect
def decorate(f):
exec(inspect.getsource(f))
return eval(f.__name__)
@decorate
def test():
return 1
Eu recebo um OSError:
OSError: could not get source code
Isso parece ser porquetest
não está totalmente formado antes de passar paradecorate
. No entanto, isso funciona:
import inspect
def decorate(f):
exec(inspect.getsource(f))
return eval(f.__name__)
def test():
return 1
test = decorate(test)
Mas ele simplesmente não tem esse talento decorador. Parece que isso pode ser possível, porquef.__code__
é definiram.
Após uma inspeção mais detalhada, parece que isso só acontece quando eu coloco oinspect.getsource(f)
para dentroexec
. Caso contrário, parece que posso obter o código fonte.
Como um esboço da primeira coisa que estou pensando, estou pensando em recursão da cauda. Eu escrevi este decorador que infelizmente é lento e requer um estilo muito específico de escrever a função a ser decorada:
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
Basicamente, estou pensando em fazer algo tão simples quanto substituir o corpo de uma função por:
while True:
__body__
update_args