Come evitare i file .pyc?


268

Posso eseguire l'interprete Python senza generare i file .pyc compilati?

Risposte:


288

Da "Novità di Python 2.6 - Modifiche all'interprete" :

Ora è possibile impedire a Python di scrivere file .pyc o .pyo fornendo l' opzione -B all'interprete Python o impostando la variabile di ambiente PYTHONDONTWRITEBYTECODE prima di eseguire l'interprete. Questa impostazione è disponibile per i programmi Python come sys.dont_write_bytecodevariabile e il codice Python può modificare il valore per modificare il comportamento dell'interprete.

Aggiornamento 2010-11-27: Python 3.2 risolve il problema del disordine delle cartelle di origine con i .pycfile introducendo una __pycache__sottocartella speciale , vedere Novità di Python 3.2 - PYC Repository Directories .


1
Almeno su OS X 10.8 con Python 2.7 la variabile d'ambiente non ha effetto.
sorin,

5
Se stai incorporando l'interprete (in un programma C ++), usa "Py_DontWriteBytecodeFlag = 1;" nel tuo codice sorgente. Questo è un int globale dichiarato in pydebug.h.
JimB,

1
La variabile d'ambiente funziona bene per me in 2.7, non so quali problemi hanno gli altri. Grazie!
Thomas,

8
Ha funzionato anche per me su OSX (10.8 e 10.10); @sorin hai esportato correttamente la variabile? export PYTHONDONTWRITEBYTECODE=1
nevelis,

1
Sai come fare lo stesso con Pytest?

110
import sys

sys.dont_write_bytecode = True

25
Ho appena provato questo e funziona per i moduli importati. In particolare, una volta impostata questa variabile, qualsiasi cosa importata successivamente non genererà file pyc. Questo è delizioso. Grazie.

Piuttosto aggiungendo questo nel modulo genitore, prova ad aggiungere questo nello script di riferimento. Funziona benissimo. Grazie a @te
Wilson

4
Aggiungi questo al tuo site-packages/usercustomize.pyper farlo applicare a tutti i tuoi script. Per me questa directory era $HOME/.local/lib/python2.6/site-pacakges/usercustomize.py. Cf. docs.python.org/2/tutorial/…
RobM

3
I miei pacchetti del sito si trovavano in: /usr/local/lib/python2.7/site-packages e ho dovuto creare usercustomize.py
anon58192932

3
O in una riga:import sys; sys.dont_write_bytecode = True
ET-CS,

23

In realtà esiste un modo per farlo in Python 2.3+, ma è un po 'esoterico. Non so se te ne rendi conto, ma puoi fare quanto segue:

$ unzip -l /tmp/example.zip
 Archive:  /tmp/example.zip
   Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32) 
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'

Secondo la libreria zipimport :

Qualsiasi file può essere presente nell'archivio ZIP, ma solo i file .py e .py [co] sono disponibili per l'importazione. L'importazione ZIP di moduli dinamici (.pyd, .so) non è consentita. Nota che se un archivio contiene solo file .py, Python non tenterà di modificare l'archivio aggiungendo il corrispondente file .pyc o .pyo, il che significa che se un archivio ZIP non contiene file .pyc, l'importazione potrebbe essere piuttosto lenta.

Quindi, tutto quello che devi fare è comprimere i file, aggiungere il file zip al tuo sys.path e quindi importarli.

Se stai costruendo questo per UNIX, potresti anche considerare di impacchettare il tuo script usando questa ricetta: eseguibile zip unix , ma tieni presente che potresti doverlo modificare se hai intenzione di usare stdin o leggere qualcosa da sys.args (può essere fatto senza troppi problemi).

Nella mia esperienza, le prestazioni non soffrono troppo a causa di ciò, ma dovresti pensarci due volte prima di importare moduli molto grandi in questo modo.


11

In 2.5, non c'è modo di sopprimerlo, a parte misure come non dare agli utenti l'accesso in scrittura alla directory.

In python 2.6 e 3.0, tuttavia, potrebbe esserci un'impostazione nel modulo sys chiamata "dont_write_bytecode" che può essere impostata per sopprimerlo. Questo può essere impostato anche passando l'opzione "-B" o impostando la variabile di ambiente "PYTHONDONTWRITEBYTECODE"


7

Puoi impostare il sys.dont_write_bytecode = Truetuo sorgente, ma dovrebbe essere nel primo file Python caricato. Se esegui python somefile.py, non otterrai somefile.pyc.

Quando installi un'utilità usando setup.pye entry_points=avrai impostato sys.dont_write_bytecodenello script di avvio. Quindi non puoi fare affidamento sullo script di avvio "predefinito" generato da setuptools.

Se avvii Python con il file python come argomento tu stesso puoi specificare -B:

python -B somefile.py

somefile.pycnon verrebbe generato comunque, ma non verranno .pycimportati anche file per altri file.

Se hai qualche utilità myutile non puoi cambiarla, non passerà -B all'interprete Python. Basta avviarlo impostando la variabile di ambiente PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil

4

Ho diversi casi di test in una suite di test e prima di eseguire la suite di test nel Terminale Mac in questo modo:

python LoginSuite.py

Eseguendo il comando in questo modo la mia directory veniva popolata con file .pyc. Ho provato il metodo indicato di seguito e ho risolto il problema:

python -B LoginSuite.py

Questo metodo funziona se si importano casi di test nella suite di test e si esegue la suite dalla riga di comando.


4

A partire da Python 3.8 è possibile utilizzare la variabile di ambiente PYTHONPYCACHEPREFIXper definire una directory cache per Python.

Dai documenti di Python:

Se impostato, Python scriverà i file .pyc in una struttura di directory mirror in questo percorso, anziché nelle directory pycache all'interno della struttura di origine. Ciò equivale a specificare l'opzione -X pycache_prefix = PATH.

Esempio

Se aggiungi la seguente riga alla tua ./profilein Linux:

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

Python non creerà le fastidiose __pycache__directory nella directory del progetto, ma le inserirà tutte~/.cache/cpython/


2

È possibile creare le directory in cui i moduli esistono in sola lettura per l'utente su cui è in esecuzione l'interprete Python.

Non penso che ci sia un'opzione più elegante. PEP 304 sembra essere stato un tentativo di introdurre una semplice opzione per questo, ma sembra essere stato abbandonato.

Immagino che ci sia probabilmente qualche altro problema che stai cercando di risolvere, per cui la disabilitazione di .py [co] sembra essere una soluzione alternativa, ma probabilmente sarà meglio attaccare qualunque sia questo problema originale.


2

Soluzione per ipython 6.2.1 using python 3.5.2(testato su Ubuntu 16.04 e Windows 10):

Ipythonnon rispetta %env PYTHONDONTWRITEBYTECODE =1se impostato ipythonnell'interprete o durante l'avvio in ~/.ipython/profile-default/startup/00-startup.ipy. Invece usando quanto segue nel tuo~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True

0

Per quanto ne so, Python compilerà tutti i moduli "importati". Tuttavia python NON compilerà uno script python eseguito usando: "python script.py" (compilerà comunque tutti i moduli importati dallo script).

La vera domanda è: perché non vuoi che Python compili i moduli? Probabilmente potresti automatizzare un modo per ripulirli se si frappongono.


Ho scoperto spesso che ci sono .pycfile bytecode non aggiornati . Per qualche motivo, quando cambio classe / modulo, il .pycfile non viene aggiornato. Quindi, quando lo importa dopo aver modificato il .pyfile, utilizzerà comunque il .pycfile, causando errori
alpha_989
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.