Wie vermeide ich .pyc-Dateien?

268

Kann ich den Python-Interpreter ausführen, ohne die kompilierten .pyc-Dateien zu generieren?

Avner
quelle

Antworten:

288

Aus "Was ist neu in Python 2.6 - Interpreter-Änderungen" :

Python kann jetzt daran gehindert werden, .pyc- oder .pyo-Dateien zu schreiben, indem der Python-Interpreter mit dem Schalter -B versehen wird oder indem die Umgebungsvariable PYTHONDONTWRITEBYTECODE festgelegt wird, bevor der Interpreter ausgeführt wird. Diese Einstellung steht Python-Programmen als sys.dont_write_bytecodeVariable zur Verfügung, und Python-Code kann den Wert ändern, um das Verhalten des Interpreters zu ändern.

Update 27.11.2010: Python 3.2 behebt das Problem, dass Quellordner mit .pycDateien überfüllt sind, indem ein spezieller __pycache__Unterordner eingeführt wird (siehe Neue Funktionen in Python 3.2 - PYC-Repository-Verzeichnisse) .

Constantin
quelle
1
Zumindest unter OS X 10.8 unter Python 2.7 hat die Umgebungsvariable keine Auswirkung.
Sorin
5
Wenn Sie den Interpreter (in ein C ++ - Programm) einbetten, verwenden Sie "Py_DontWriteBytecodeFlag = 1;" in Ihrem Quellcode. Das ist ein globaler int, der in pydebug.h deklariert ist.
JimB
1
Die Umgebungsvariable funktioniert in 2.7 einwandfrei. Ich weiß nicht, welche Probleme andere haben. Vielen Dank!
Thomas
8
Arbeitete auch für mich unter OSX (10.8 & 10.10); @sorin hast du die Variable richtig exportiert? export PYTHONDONTWRITEBYTECODE=1
Nevelis
1
Wissen Sie, wie man dasselbe mit Pytest macht?
110
import sys

sys.dont_write_bytecode = True
te wilson
quelle
25
Ich habe es gerade versucht und es funktioniert für importierte Module. Sobald diese Variable festgelegt ist, werden durch später importierte Elemente keine Pyc-Dateien generiert. Das ist herrlich. Vielen Dank.
Versuchen Sie stattdessen, dies im übergeordneten Modul hinzuzufügen, und fügen Sie dies im referenzierten Skript hinzu. Das funktioniert cool. Vielen Dank an @te Wilson
Sathy
4
Fügen Sie dies zu Ihrem hinzu site-packages/usercustomize.py, damit dies auf alle Ihre Skripte angewendet wird. Für mich war dieses Verzeichnis $HOME/.local/lib/python2.6/site-pacakges/usercustomize.py. Vgl. docs.python.org/2/tutorial/…
RobM
3
Meine Site-Pakete befanden sich unter: /usr/local/lib/python2.7/site-packages und ich musste usercustomize.py erstellen
anon58192932
3
Oder in einer Zeile:import sys; sys.dont_write_bytecode = True
ET-CS
23

In Python 2.3+ gibt es tatsächlich eine Möglichkeit, dies zu tun, aber es ist ein bisschen esoterisch. Ich weiß nicht, ob Sie das erkennen, aber Sie können Folgendes tun:

$ 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'

Laut der Zipimport- Bibliothek:

Alle Dateien können im ZIP-Archiv vorhanden sein, aber nur die Dateien .py und .py [co] können importiert werden. Der ZIP-Import von dynamischen Modulen (.pyd, .so) ist nicht zulässig. Beachten Sie, dass Python, wenn ein Archiv nur .py-Dateien enthält, nicht versucht, das Archiv durch Hinzufügen der entsprechenden .pyc- oder .pyo-Datei zu ändern. Wenn ein ZIP-Archiv keine .pyc-Dateien enthält, ist der Import möglicherweise sehr langsam.

Alles, was Sie tun müssen, ist, die Dateien zu komprimieren, die Zip-Datei zu Ihrem sys.path hinzuzufügen und sie dann zu importieren.

Wenn Sie dies für UNIX erstellen, können Sie Ihr Skript auch nach folgendem Rezept packen : Unix zip ausführbar . Beachten Sie jedoch, dass Sie dies möglicherweise anpassen müssen, wenn Sie stdin verwenden oder etwas aus sys.args lesen möchten (es KANN sein) ohne zu viel Mühe gemacht).

Nach meiner Erfahrung leidet die Leistung nicht allzu sehr darunter, aber Sie sollten zweimal überlegen, bevor Sie sehr große Module auf diese Weise importieren.

Jason Baker
quelle
11

In 2.5 gibt es keine Möglichkeit, dies zu unterdrücken, außer Maßnahmen, wie Benutzern keinen Schreibzugriff auf das Verzeichnis zu gewähren.

In Python 2.6 und 3.0 gibt es jedoch möglicherweise eine Einstellung im sys-Modul namens "dont_write_bytecode", die festgelegt werden kann, um dies zu unterdrücken. Dies kann auch durch Übergeben der Option "-B" oder durch Setzen der Umgebungsvariablen "PYTHONDONTWRITEBYTECODE" festgelegt werden.

Brian
quelle
7

Sie können sys.dont_write_bytecode = Truein Ihrer Quelle festlegen , aber das müsste in der ersten geladenen Python-Datei sein. Wenn Sie ausführen, erhalten python somefile.pySie nicht somefile.pyc.

Wenn Sie ein Dienstprogramm mit installieren setup.pyund haben entry_points=Sie sys.dont_write_bytecodeim Startskript festgelegt. Sie können sich also nicht auf das von setuptools generierte "Standard" -Start-Skript verlassen.

Wenn Sie Python selbst mit einer Python-Datei als Argument starten, können Sie Folgendes angeben -B:

python -B somefile.py

somefile.pycwürde sowieso nicht generiert, aber keine .pycDateien für andere Dateien auch importiert.

Wenn Sie ein Dienstprogramm haben myutilund dieses nicht ändern können, wird -B nicht an den Python-Interpreter übergeben. Starten Sie es einfach, indem Sie die Umgebungsvariable festlegen PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil
Elwyne
quelle
4

Ich habe mehrere Testfälle in einer Testsuite und bevor ich die Testsuite im Mac Terminal wie folgt ausgeführt habe:

python LoginSuite.py

Wenn Sie den Befehl auf diese Weise ausführen, wurde mein Verzeichnis mit .pyc-Dateien gefüllt. Ich habe die unten angegebene Methode ausprobiert und das Problem behoben:

python -B LoginSuite.py

Diese Methode funktioniert, wenn Sie Testfälle in die Testsuite importieren und die Suite in der Befehlszeile ausführen.

Ravil Asadov
quelle
4

Ab Python 3.8 können Sie mit der Umgebungsvariablen PYTHONPYCACHEPREFIXein Cache-Verzeichnis für Python definieren.

Aus den Python-Dokumenten:

Wenn dies festgelegt ist, schreibt Python .pyc-Dateien in einen Spiegelverzeichnisbaum unter diesem Pfad anstatt in pycache- Verzeichnisse innerhalb des Quellbaums . Dies entspricht der Angabe der Option -X pycache_prefix = PATH.

Beispiel

Wenn Sie Ihrem ./profileLinux die folgende Zeile hinzufügen :

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

Python erstellt nicht die nervigen __pycache__Verzeichnisse in Ihrem Projektverzeichnis, sondern legt sie alle ab~/.cache/cpython/

Rotareti
quelle
2

Sie können die Verzeichnisse, in denen Ihre Module vorhanden sind, für den Benutzer, unter dem der Python-Interpreter ausgeführt wird, schreibgeschützt machen.

Ich denke nicht, dass es eine elegantere Option gibt. PEP 304 scheint ein Versuch gewesen zu sein, eine einfache Option dafür einzuführen, aber es scheint aufgegeben worden zu sein.

Ich kann mir vorstellen, dass es wahrscheinlich ein anderes Problem gibt, das Sie lösen möchten. Das Deaktivieren von .py [co] scheint eine Problemumgehung zu sein, aber es ist wahrscheinlich besser, stattdessen das ursprüngliche Problem anzugreifen.

Logan
quelle
2

Lösung für ipython 6.2.1 using python 3.5.2(Getestet unter Ubuntu 16.04 und Windows 10):

Ipythonwird nicht berücksichtigt, %env PYTHONDONTWRITEBYTECODE =1wenn im ipythonInterpretor oder beim Start in eingestellt ~/.ipython/profile-default/startup/00-startup.ipy. Verwenden Sie stattdessen Folgendes in Ihrem~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True
alpha_989
quelle
0

Soweit ich weiß, kompiliert Python alle Module, die Sie "importieren". Python kompiliert jedoch KEIN Python-Skript, das mit "python script.py" ausgeführt wird (es kompiliert jedoch alle Module, die das Skript importiert).

Die eigentliche Frage ist, warum Python die Module nicht kompilieren soll. Sie könnten wahrscheinlich einen Weg automatisieren, diese zu bereinigen, wenn sie im Weg sind.

Alex
quelle
Ich habe häufig festgestellt, dass es veraltete Bytecode- .pycDateien gibt. Wenn ich die Klasse / das Modul ändere, wird die .pycDatei aus irgendeinem Grund nicht aktualisiert. Wenn ich es nach dem Ändern der .pyDatei importiere , wird es weiterhin verwendet .pyc, was zu Fehlern führt
alpha_989