Modificar función en decorador
Estaba pensando en hacer un decorador con el fin de aumentar el rendimiento. Un decorador que modifica el código fuente de la función que decora y devuelve la función modificada.
Mientras pensaba en esto, pensé que si pudiera obtener el código fuente de la función, podría hacerlo. Pero, ¿es posible acceder al código fuente de una función dentro de un decorador? Si tengo un decorador como este:
import inspect
def decorate(f):
exec(inspect.getsource(f))
return eval(f.__name__)
@decorate
def test():
return 1
Me sale un OSError:
OSError: could not get source code
Esto parece ser porquetest
no está completamente formado antes de pasarlo adecorate
. Sin embargo, esto funciona:
import inspect
def decorate(f):
exec(inspect.getsource(f))
return eval(f.__name__)
def test():
return 1
test = decorate(test)
Sin embargo, simplemente no tiene ese toque de decorador. Parece que esto podría ser posible, porquef.__code__
es definido.
Tras una inspección adicional, parece que esto solo sucede cuando pongo elinspect.getsource(f)
dentroexec
. De lo contrario, parece que puedo obtener el código fuente.
Como bosquejo de lo primero que tengo en mente, estoy pensando en la recursión de la cola. Escribí este decorador que desafortunadamente es lento y requiere un estilo muy específico de escritura para decorar la función:
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
Básicamente, estoy pensando en hacer algo tan simple como reemplazar el cuerpo de una función con:
while True:
__body__
update_args