He estado experimentando con AST en python. Quiero modificar los métodos transformando los AST en tiempo de ejecución.Compilar python AST con el método
Puedo obtener el origen de un método precompilado usando inspect.getsource()
, y Puedo modificar el AST según lo requieran los visitantes de AST.
Ésta es probablemente bastante ingenuo, pero me gustaría ser capaz de compilar el AST y hacer algo similar a:
myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec')
Pero compilar sólo aceptará un AST con un ast.Module como root. ¿Hay alguna forma de compilar solo un ast.FunctionDef, o recuperar el objeto del código de función del código del módulo compilado (y de lo contrario vacío)?
Se agradecerá cualquier información que cubra este tipo de cosas. Los ejemplos de AST que he visto solo tratan con expresiones simples.
Me di cuenta de que necesitaba simplemente ejecutar el módulo en un espacio de nombres, y luego tendría acceso a la estructura normal. Así que el patrón es:
src = inspect.getsource(myClass.myMethod)
astFromSrc = ast.parse(unindent(src)) # need to remove extra indent from method
transform(astFromSrc.body) # transform the AST as you need
ast.fix_missing_locations(astFromSrc) # fix up line numbers etc
compiled = compile(astFromSrc, '<string>', 'exec') # compile the module AST
####### From here is the part I was missing
myScope = {} # make an empty namespace
exec compiled in myScope # now myScope contains a proper compiled function
# Now replace the original with the modified version
myClass.myMethod.__func__.__code__ = myScope['myMethod'].__code__
Pero ahora tengo otra pregunta: ¿Cómo A la ranura presente en el proceso de construcción de pitón normal, de modo que las modificaciones se realizan una sola vez, y después de eso cargan desde el archivo .pyc?
Dado que descubrió la respuesta a su pregunta, publíquela como respuesta y acéptela. – cpburnz