Entiendo que los archivos ".pyc" son versiones compiladas de los archivos ".py" de texto plano, creados en tiempo de ejecución para que los programas se ejecuten más rápido. Sin embargo, he observado algunas cosas:
- Tras la modificación de archivos "py", el comportamiento del programa cambia. Esto indica que los archivos "py" están compilados o al menos pasan por algún tipo de proceso de hash o comparan marcas de tiempo para saber si deben volver a compilarse o no.
- Al eliminar todos los archivos ".pyc" (
rm *.pyc
), algunas veces el comportamiento del programa cambiará. Lo que indicaría que no se están compilando en la actualización de ".py" s.
Preguntas:
- ¿Cómo deciden cuándo se compilan?
- ¿Hay alguna forma de garantizar que tengan un control más estricto durante el desarrollo?
python
python-internals
pyc
Aaron Schif
fuente
fuente
rm *.pyc
. Esto no eliminará los archivos .pyc en carpetas anidadas. Úselo en sufind . -name '*.pyc' -delete
lugarRespuestas:
Los
.pyc
archivos se crean (y posiblemente se sobrescriben) solo cuando ese archivo de Python es importado por algún otro script. Si se llama a la importación, Python comprueba si la.pyc
marca de tiempo interna del archivo no es anterior al.py
archivo correspondiente . Si es así, carga el.pyc
; si no lo es o si.pyc
aún no existe, Python compila el.py
archivo en a.pyc
y lo carga.¿Qué quiere decir con "control más estricto"?
fuente
rm *.pyc
. Sé que si fuerzo la recreación de todos los archivos, se solucionan algunos problemas, lo que indica que los archivos no se vuelven a compilar por sí mismos. Supongo que si usan las marcas de tiempo, no hay forma de hacer que este comportamiento sea más estricto, pero el problema persiste..pyc
marca de tiempo 'debe ser más antigua que la.py
marca de tiempo correspondiente para activar una recompilación.Archivos .pyc generados cada vez que se importan los elementos de código correspondientes y se actualizan si los archivos de código correspondientes se han actualizado. Si se eliminan los archivos .pyc, se volverán a generar automáticamente. Sin embargo, no se eliminan automáticamente cuando se eliminan los archivos de código correspondientes.
Esto puede causar algunos errores realmente divertidos durante la refactorización a nivel de archivo.
En primer lugar, puede terminar enviando un código que solo funciona en su máquina y en la de nadie más. Si tiene referencias colgantes a archivos que eliminó, estos seguirán funcionando localmente si no elimina manualmente los archivos .pyc relevantes porque los archivos .pyc se pueden usar en las importaciones. Esto se agrava con el hecho de que un sistema de control de versiones configurado correctamente solo enviará archivos .py al repositorio central, no archivos .pyc, lo que significa que su código puede pasar la "prueba de importación" (todo se importa bien) sin problemas y no trabajar en la computadora de otra persona.
En segundo lugar, puede tener algunos errores bastante terribles si convierte los paquetes en módulos. Cuando convierte un paquete (una carpeta con un
__init__.py
archivo) en un módulo (un archivo .py), los archivos .pyc que alguna vez representaron ese paquete permanecen. En particular, los__init__.pyc
restos. Entonces, si tiene el paquete foo con algún código que no importa, luego elimine ese paquete y cree un archivo foo.py con alguna funcióndef bar(): pass
y ejecute:usted obtiene:
porque python todavía está usando los archivos .pyc antiguos del paquete foo, ninguno de los cuales define bar. Esto puede ser especialmente problemático en un servidor web, donde el código totalmente funcional puede romperse debido a archivos .pyc.
Como resultado de estos dos motivos (y posiblemente otros), su código de implementación y el código de prueba deben eliminar los archivos .pyc, como con la siguiente línea de bash:
Además, a partir de Python 2.6, puede ejecutar Python con la
-B
bandera para no usar archivos .pyc. Consulte ¿Cómo evitar los archivos .pyc? para más detalles.Consulte también: ¿Cómo elimino todos los archivos .pyc de un proyecto?
fuente
__init__.py
archivo) ...". Eso sería un paquete, no un módulo.__init__.pyc
restos. - ¿Cómo? Como un paquete es un directorio, eliminar un paquete significa eliminar el directorio, por lo que no quedan archivos….pyc
problema también es una razón: dependencias ocultas en el sistema operativo y los niveles de parches de utilidad,.so
archivos , archivos de configuración, otras bibliotecas de Python (si no está ejecutando en un entorno virtual), vars de entorno oscuras ... la lista continúa. Para ser minucioso y encontrar todos estos problemas, debe hacer una copia limpia de su código en un repositorio de git o publicar como un paquete en un servidor de estilo PyPi, y hacer una clonación completa o una configuración en una máquina virtual nueva. Algunos de esos problemas potenciales hacen que este.pyc
problema palidezca en comparación.