2010-08-17 20 views
21

¿Hay alguna manera de hacer que Python ignore cualquier archivo .pyc que esté presente y siempre interprete todo el código (incluidos los módulos importados) directamente? Google no ha encontrado ninguna respuesta, así que sospecho que no, pero me pareció que valía la pena preguntarlo por las dudas.Hacer que Python ignore los archivos .pyc

(¿Por qué quiero hacer esto? Tengo una gran cantidad de scripts de Python que se ejecutan repetidamente en un clúster de un par de cientos de computadoras. Los scripts de Python en sí mismos viven en un sistema de archivos NFS compartido. habiendo sido ejecutados cientos de veces durante varias horas, de repente comenzarán a fallar con un error sobre la imposibilidad de importar un módulo. Forzar la regeneración del archivo .pyc soluciona el problema. Quiero, por supuesto, corregir las causas subyacentes , pero mientras tanto también necesitamos que el sistema continúe funcionando, por lo que parece que ignorar los archivos .pyc si es posible sería una solución razonable).

P.S. Estoy usando Python 2.5, así que no puedo usar -B.

Respuesta

12

Usted podía utilizar el módulo imp de la biblioteca estándar de Python para reimplementar __builtins__.__import__, que es la función de enlace llamado por import y from comunicado. En particular, la función imp.load_module se puede utilizar para cargar un .py incluso cuando está presente el .pyc correspondiente. Asegúrese de estudiar cuidadosamente todos los documentos de la página que he señalado, más los de import, ya que es un trabajo delicado. Los documentos en sí sugieren usar ganchos de importación en su lugar (por PEP 302) pero para esta tarea en particular, sospecho que sería aún más difícil.

Por cierto, las causas probables de sus problemas observados incluyen las condiciones de carrera entre diferentes computadoras que intentan escribir .pyc archivos al mismo tiempo - El bloqueo NFS es notoriamente escamoso y siempre ha sido ;-). Siempre que todos los compiladores de Python que utilizas estén en la misma versión (si no, estás en un gran problema ;-), preferiría precompilar todos esos archivos .py en .pyc y hacer que sus directorios sean de solo lectura; este último parece el enfoque más simple de todos modos (en lugar de hackear __import__), incluso si por alguna razón no puede precompilar.

0

Quizás podría solucionar esto, por ejemplo, programando un trabajo para cerrar periódicamente los scripts y eliminar los archivos .pyc.

11

No es exactamente lo que pediste, pero ¿eliminarías los archivos .pyc existentes y luego no crearías más trabajo para ti? En ese caso, se puede utilizar la opción -B:

>python --help 
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... 
Options and arguments (and corresponding environment variables): 
-B  : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x 
+0

Eso sería genial, en realidad, excepto que desafortunadamente por razones fuera de mi control, estoy atascado con Python 2.5, que no tiene -B. Debería haber mencionado eso en la pregunta, lo siento! –

0

Bueno, no creo que Python alguna vez interprete código directamente si está cargando el código de un archivo. Incluso cuando se utiliza el shell interactivo, Python compilará el módulo importado en .pyc.

Dicho esto, podría escribir un script de shell para continuar y eliminar todos los archivos .pyc antes de iniciar sus scripts. Eso ciertamente forzaría una reconstrucción completa antes de cada ejecución.

5

En caso de que alguien está usando Python 2.6 o superior con la misma pregunta, la cosa más sencilla de hacerlo es:

  1. eliminar todos los archivos .pyc
  2. ejecutar todos los intérpretes de pitón con la opción -B, por lo no generarán archivos .pyc.

A partir de los documentos:

-B Si se les da, Python no intentará escribir .pyc o archivos .pyo a la importación de módulos de origen. Ver también PYTHONDONTWRITEBYTECODE.

Nuevo en la versión 2.6.

Si no puede eliminar todos los .pycs, entonces se podría:

1) Ejecutar todos sus intérpretes pitón con las opciones -B -O.

Esto le dirá a python que busque archivos .pyo para bytecode en lugar de archivos .pyc (-O) y diga a python que no genere ningún archivo de código de bytes (-B).

La combinación de las dos opciones, suponiendo que no las haya usado antes, es que Python no generará ningún archivo de código de bytes y no buscará los archivos bytecode que se generarían en ejecuciones anteriores.

A partir de los documentos:

-B Si se les da, Python no intentará escribir .pyc o archivos .pyo a la importación de módulos de origen. Ver también PYTHONDONTWRITEBYTECODE.

Nuevo en la versión 2.6.

-O Active las optimizaciones básicas. Esto cambia la extensión de nombre de archivo para los archivos compilados (bytecode) de .pyc a .pyo. Ver también PYTHONOPTIMIZE.

Cuestiones relacionadas