¿Cómo diferenciar entre “una cadena” y “un código real” en python?

Mis trabajos se relacionan con la instrumentación de fragmentos de código en código python. Por lo tanto, en mi trabajo, estaría escribiendo un script en python de modo que tomo otro archivo de python como entrada e inserto cualquier código necesario en el lugar requerido con mi script.

El siguiente código es un código de muestra de un archivo que estaría instrumentando:

A.py #normal un-instrumented code statements .... .... def move(self,a): statements ...... print "My function is defined" ...... statements ...... 

Mi script lo que realmente hace es verificar cada línea en el A.py y si hay una “def” entonces un fragmento de código se implementa encima del código de la función def

El siguiente ejemplo es cómo debe ser la salida final:

 A.py #instrumented code statements .... .... @decorator #<------ inserted code def move(self,a): statements ...... print "My function is defined" ...... statements ...... 

Pero me han salido con diferente salida. El siguiente código es el resultado final que estoy obteniendo:

A.py # código instrumentado

 statements .... .... @decorator #<------ inserted code def move(self,a): statements ...... @decorator #<------ inserted code [this should not occur] print "My function is defined" ...... statements ...... 

Puedo entender que en el código instrumentado reconoce “def” en la palabra “definido” y, por lo tanto, implementa un código arriba.

En realidad, el código instrumentado tiene muchos de estos problemas. No pude instrumentar correctamente el archivo de Python dado. ¿Hay alguna otra manera de diferenciar la “def” real de la cadena?

Gracias

Utilice el módulo ast para analizar el archivo correctamente.

Este código imprime el número de línea y el desplazamiento de columna de cada instrucción def :

 import ast with open('mymodule.py') as f: tree = ast.parse(f.read()) for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): print node.lineno, node.col_offset 

Podrías usar una Expresión Regular. Para evitar las citas dentro de la def entonces puedes usar look-around negativos:

 import re for line in open('A.py'): m = re.search(r"(?!<[\"'])\bdef\b(?![\"'])", line) if m: print r'@decorator #<------ inserted code' print line 

Sin embargo, podría haber otras ocurrencias de def que usted o yo no podamos imaginar, y si no tenemos cuidado, terminamos escribiendo el analizador de Python de nuevo. La sugerencia de @Janne Karila de usar ast.parse es probablemente más segura a largo plazo.