2011-08-15 19 views
9

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?

+2

Dado que descubrió la respuesta a su pregunta, publíquela como respuesta y acéptela. – cpburnz

Respuesta

1

No debe hacer una nueva pregunta en su propia respuesta sino crear una pregunta separada para eso.

Tenga en cuenta que su primera y segunda pregunta también se contradicen. Primero quiere hacer cosas en tiempo de ejecución y luego desea escribirlas en un archivo para que no tenga que hacerlo una y otra vez. Indique su objetivo final para que sepamos claramente lo que desea.

Suena como que sólo podría así crear un nuevo archivo .py después de modificar el ast de un archivo que se analiza como se explica en Parse a .py file, read the AST, modify it, then write back the modified source code

, a continuación, obtener su archivo PYC compilando el py recién creado archivo.