¿Qué es __pycache__?

653

Por lo que entiendo, un caché es un archivo cifrado de archivos similares.

¿Qué hacemos con la __pycache__carpeta? ¿Es lo que le damos a las personas en lugar de nuestro código fuente? ¿Son solo mis datos de entrada? Esta carpeta se sigue creando, ¿para qué sirve?

usuario2063042
fuente
29
"¿Es lo que le damos a las personas en lugar de nuestro código fuente?" - No, les das el código fuente en un bonito paquete instalable para que sea fácil de usar.
Lennart Regebro
79
Nadie lo mencionó todavía, pero su definición de caché es extraña. La memoria caché es simplemente un componente que almacena datos para que las solicitudes futuras de esos datos se puedan atender más rápido .
Ricardo Cruz
44
Ver: python.org/dev/peps/pep-3147
Mr_and_Mrs_D
1
Como Python 3.8puede usar una variable de entorno para cambiar la ubicación de los directorios de caché molestos: stackoverflow.com/a/57414308/1612318
Rotareti
Un caché es algo que guarda una copia de las cosas en caso de que lo necesite nuevamente, para evitar tener que volver al original para obtenerlo. Está diseñado para ser más rápido que ir al lugar original. Puede ser más rápido porque no tiene que preprocesar o compilar la información. O podría ser un almacenamiento más rápido, por ejemplo, un caché de disco en RAM o un caché web en un disco local. No está encriptado por naturaleza (aunque a veces podría estarlo), y no siempre es un "archivo de archivos similares"; puede ser un archivo, una carga de archivos, un bloque de RAM, etc.
rjmunro

Respuestas:

519

Cuando ejecuta un programa en python, el intérprete lo compila primero en bytecode (esto es una simplificación excesiva) y lo almacena en la __pycache__carpeta. Si observa allí, encontrará un montón de archivos que comparten los nombres de los archivos .py en la carpeta de su proyecto, solo sus extensiones serán .pyc o .pyo. Estas son versiones compiladas por bytecode y compiladas por bytecode de los archivos de su programa, respectivamente.

Como programador, puede ignorarlo en gran medida ... Todo lo que hace es hacer que su programa se inicie un poco más rápido. Cuando cambien sus scripts, se volverán a compilar, y si elimina los archivos o la carpeta completa y ejecuta su programa nuevamente, volverán a aparecer (a menos que suprima específicamente ese comportamiento)

Si está utilizando cpython (que es el más común, ya que es la implementación de referencia) y no desea esa carpeta, puede suprimirla iniciando el intérprete con el indicador -B, por ejemplo

python -B foo.py

Otra opción, como señaló tcaswell, es establecer la variable de entorno PYTHONDONTWRITEBYTECODEen cualquier valor (de acuerdo con la página de manual de python, cualquier "cadena no vacía").

scott_fakename
fuente
48
También puede agregar la variable de entorno PYTHONDONTWRITEBYTECODE=<any_value>para suprimirla permanentemente.
Mark Tolonen
11
Solo para aclarar, esto es solo para Python 3, ¿correcto?
Joe J
11
@ Joe, sí, creo que es verdad. python2coloca los archivos compilados en el mismo directorio que los originales, si no me equivoco.
scott_fakename
27
Una advertencia IMPORTANTE es que el archivo .pyc en caché se usará en lugar del archivo .py si falta el archivo .py. En la práctica, esto solo sucede si elimina (o cambia el nombre) de los módulos, por lo que no es una ocurrencia común, pero si algunas cosas siguen "allí", después de rascarse la cabeza, ejecutar find. -name * .pyc | xargs rm en su fuente es probablemente una buena primera reacción.
yacc143
34
find . -name '*.pyc' -deleteSí, find tiene una bandera para eliminar los archivos encontrados, por lo que no tiene que usar ningún shananigans xargs
vlad-ardelean
175

__pycache__es una carpeta que contiene el bytecode de Python 3 compilado y listo para ejecutarse .

No recomiendo eliminar estos archivos de forma rutinaria o suprimir la creación durante el desarrollo, ya que puede dañar el rendimiento. Solo tenga un comando recursivo listo (vea a continuación) para limpiar cuando sea necesario, ya que el bytecode puede volverse obsoleto en casos extremos (ver comentarios).

Los programadores de Python generalmente ignoran el código de bytes. De hecho __pycache__y *.pycson líneas comunes para ver en los .gitignorearchivos. El código de bytes no está destinado a la distribución y puede desmontarse usando el dismódulo .


Si está utilizando OS X, puede ocultar fácilmente todas estas carpetas en su proyecto ejecutando el siguiente comando desde la carpeta raíz de su proyecto.

find . -name '__pycache__' -exec chflags hidden {} \;

Reemplace __pycache__con *.pycpara Python 2.

Esto establece una marca en todos esos directorios (archivos .pyc) que le indica a Finder / Textmate 2 que los excluya de las listas. Es importante destacar que el código de bytes está ahí, simplemente está oculto.

Vuelva a ejecutar el comando si crea nuevos módulos y desea ocultar un nuevo código de bytes o si elimina los archivos ocultos.


En Windows, el comando equivalente podría ser (no probado, bienvenida secuencia de comandos por lotes):

dir * /s/b | findstr __pycache__ | attrib +h +s +r

Lo que es lo mismo que pasar por el proyecto ocultando carpetas usando el botón derecho> ocultar ...


Ejecutar pruebas unitarias es un escenario (más en los comentarios) donde eliminar los *.pycarchivos y __pycache__carpetas es realmente útil. Utilizo las siguientes líneas en mi ~/.bash_profiley solo corro clpara limpiar cuando es necesario.

alias cpy='find . -name "__pycache__" -delete'
alias cpc='find . -name "*.pyc"       -delete'
...
alias cl='cpy && cpc && ...'
salto de línea
fuente
¿No se desharía esto cada vez que ejecutas el código?
Holloway
2
@DoTheEvo: simplemente no se crea, por lo que no hay aceleración la próxima vez que se carga el módulo. No se genera ningún error.
Petr Viktorin
77
Esta no es una buena respuesta. El autor de la pregunta quiere saber para qué sirven estos archivos. Esta respuesta dice "no te preocupes por eso" y luego los hace desaparecer.
curiosamente allí
36
Absolutamente molesta eliminarlos : no tiene sentido. Python felizmente no detectará cambios en el archivo y se ejecutará en un archivo de caché en muchas circunstancias, llevándote por la pared con "por qué la f todavía no funciona, cambié el código, por qué sigue fallando en llamadas inexistentes" sin sentido. Especialmente en marcos de prueba, pycache-by-default es lo peor.
Mike 'Pomax' Kamermans
2
No estoy de acuerdo con este consejo para "no molestarme en eliminar estos archivos". He visto esto recomendado muchas veces, más recientemente por "How To Python" de Kenneth Reitz ("el truco del código de bytes")
Louis Maddox
38

Se __pycache__crea una carpeta cuando usa la línea:

import file_name

o intente obtener información de otro archivo que haya creado. Esto lo hace un poco más rápido cuando ejecuta su programa por segunda vez para abrir el otro archivo.

Aleks S.
fuente
27

Respuesta actualizada de más de 3.7 documentos:

Para acelerar la carga de módulos, Python almacena en caché la versión compilada de cada módulo en el __pycache__directorio bajo el nombre module.version.pyc, donde la versión codifica el formato del archivo compilado; generalmente contiene el número de versión de Python. Por ejemplo, en CPython versión 3.3, la versión compilada de spam.py se almacenaría en caché como __pycache__/spam.cpython-33.pyc. Esta convención de nomenclatura permite que coexistan módulos compilados de diferentes versiones y diferentes versiones de Python.

Fuente: https://docs.python.org/3/tutorial/modules.html#compiled-python-files

Es decir, este directorio es generado por Python y existe para hacer que sus programas se ejecuten más rápido. No debe estar comprometido con el control de la fuente, y debe coexistir en paz con su código fuente local.


__pycache__es un directorio que contiene archivos de caché de código de bytes que python genera automáticamente, es decir .pyc, archivos compilados de python o . Quizás se pregunte por qué Python, un lenguaje "interpretado", tiene algún archivo compilado. Esta pregunta SO aborda eso (y definitivamente vale la pena leer esta respuesta ).

Los documentos de Python profundizan más sobre cómo funciona exactamente y por qué existe:

  • Se agregó en python 3.2 porque el sistema existente de mantenimiento de .pycarchivos en el mismo directorio causó varios problemas, como cuando se ejecutó un programa con intérpretes de Python de diferentes versiones. Para la especificación de características completas, consulte PEP 3174 .
FluxLemur
fuente
5

de los módulos de tutoriales oficiales de Python

Para acelerar la carga de módulos, Python almacena en caché la versión compilada de cada módulo en el __pycache__directorio bajo el nombre module.version.pyc, donde la versión codifica el formato del archivo compilado; generalmente contiene el número de versión de Python. Por ejemplo, en CPython versión 3.6, la versión compilada de spam.py se almacenaría en caché como __pycache__/spam.cpython-36.pyc.

de las preguntas frecuentes sobre programación de Python doc

Cuando se importa un módulo por primera vez (o cuando el archivo fuente ha cambiado desde que se creó el archivo compilado actual), se debe crear un archivo .pyc que contenga el código compilado en un __pycache__subdirectorio del directorio que contiene el .pyarchivo. El .pycarchivo tendrá un nombre de archivo que comienza con el mismo nombre que el .pyarchivo y termina .pyccon un componente intermedio que depende del binario particular de Python que lo creó.

Yossarian42
fuente
5

La ejecución de una secuencia de comandos de Python provocaría que el código de bytes se genere en la memoria y se mantenga hasta que se cierre el programa. En caso de que se importe un módulo, para una reutilización más rápida, Python crearía un archivo .pyc de caché (PYC es 'Python' 'Compilado') donde se almacena en caché el código de bytes del módulo que se está importando. La idea es acelerar la carga de los módulos de Python evitando la recompilación (compilar una vez, ejecutar la política varias veces) cuando se vuelven a importar.

El nombre del archivo es el mismo que el nombre del módulo. La parte posterior al punto inicial indica la implementación de Python que creó el caché (podría ser CPython) seguido de su número de versión.

TechFree
fuente
3

El intérprete de Python compila el archivo de script * .py y guarda los resultados de la compilación en el __pycache__directorio.

Cuando el proyecto se ejecuta nuevamente, si el intérprete identifica que el script * .py no se ha modificado, omite el paso de compilación y ejecuta el archivo * .pyc generado previamente almacenado en la __pycache__carpeta.

Cuando el proyecto es complejo, puede hacer que el tiempo de preparación sea más corto. Si el programa es demasiado pequeño, puede ignorarlo utilizando python -B abc.pyla Bopción.

Marcus Thornton
fuente
3

Python Versión 2.x tendrá .pyc cuando el intérprete compile el código.

Python Versión 3.x tendrá __pycache__ cuando el intérprete compile el código.

alok@alok:~$ ls
module.py  module.pyc  __pycache__  test.py
alok@alok:~$
Alok Tiwari
fuente
2

En 3.2 y versiones posteriores, Python guarda los archivos de código de bytes compilados .pyc en un subdirectorio __pycache__ubicado en el directorio donde residen sus archivos fuente con nombres de archivo que identifican la versión de Python que los creó (por ejemplo, script.cpython-33.pyc)

Shashidhar Yalagi
fuente
¿Cómo puedo evitar la creación de la carpeta " pycache " y todos los archivos .pyc deben tener el mismo nombre que el archivo .py?
Ashwani
1

Cuando importas un módulo ,

import file_name

Python almacena el bytecode compilado en el __pycache__directorio para que las futuras importaciones puedan usarlo directamente, en lugar de tener que analizar y compilar la fuente nuevamente.

No hace eso simplemente ejecutando un script, solo cuando se importa un archivo.

(Las versiones anteriores solían almacenar el bytecode en caché como archivos .pyc que llenaban el mismo directorio que los archivos .py, pero a partir de Python 3 se movieron a un subdirectorio para hacer las cosas más ordenadas).

PYTHONDONTWRITEBYTECODE ---> Si se configura en una cadena no vacía, Python no intentará escribir archivos .pyc en la importación de módulos fuente. Esto es equivalente a especificar la opción -B.

Ehsan Barkhordar
fuente