Ich verstehe, dass ".pyc" -Dateien kompilierte Versionen der Klartext ".py" -Dateien sind, die zur Laufzeit erstellt wurden, um die Ausführung von Programmen zu beschleunigen. Ich habe jedoch einige Dinge beobachtet:
- Beim Ändern von "py" -Dateien ändert sich das Programmverhalten. Dies zeigt an, dass die "py" -Dateien kompiliert werden oder zumindest einen Hashing-Prozess durchlaufen oder Zeitstempel vergleichen, um festzustellen, ob sie neu kompiliert werden sollen oder nicht.
- Beim Löschen aller ".pyc" -Dateien (
rm *.pyc
) ändert sich manchmal das Programmverhalten. Was darauf hinweisen würde, dass sie beim Update von ".py" nicht kompiliert werden.
Fragen:
- Wie entscheiden sie, wann sie kompiliert werden sollen?
- Gibt es eine Möglichkeit, um sicherzustellen, dass sie während der Entwicklung strenger überprüft werden?
python
python-internals
pyc
Aaron Schif
quelle
quelle
rm *.pyc
. Dadurch werden keine .pyc-Dateien in verschachtelten Ordnern gelöscht. Verwenden Siefind . -name '*.pyc' -delete
stattdessenAntworten:
Die
.pyc
Dateien werden nur erstellt (und möglicherweise überschrieben), wenn diese Python-Datei von einem anderen Skript importiert wird. Wenn der Import aufgerufen wird, prüft Python, ob der.pyc
interne Zeitstempel der Datei nicht älter als die entsprechende.py
Datei ist. Wenn dies der Fall ist, wird das geladen.pyc
. Wenn dies nicht der.pyc
Fall ist oder noch nicht vorhanden ist, kompiliert Python die.py
Datei in a.pyc
und lädt sie.Was meinst du mit "strengerer Kontrolle"?
quelle
rm *.pyc
. Ich weiß, dass einige Probleme behoben werden, wenn ich erzwinge, dass alle Dateien neu erstellt werden, was darauf hinweist, dass die Dateien nicht selbst neu kompiliert werden. Ich nehme an, wenn sie die Zeitstempel verwenden, gibt es keine Möglichkeit, dieses Verhalten zu verschärfen, aber das Problem besteht weiterhin..pyc
Zeitstempel des 'muss älter sein als der.py
Zeitstempel des entsprechenden , um eine Neukompilierung auszulösen..pyc-Dateien werden generiert, wenn die entsprechenden Codeelemente importiert werden, und aktualisiert, wenn die entsprechenden Code-Dateien aktualisiert wurden. Wenn die .pyc-Dateien gelöscht werden, werden sie automatisch neu generiert. Sie werden jedoch nicht automatisch gelöscht, wenn die entsprechenden Codedateien gelöscht werden.
Dies kann einige wirklich lustige Fehler bei Refactors auf Dateiebene verursachen.
Zuallererst können Sie Code pushen, der nur auf Ihrem Computer und auf keinem anderen funktioniert. Wenn Sie Verweise auf gelöschte Dateien haben, funktionieren diese weiterhin lokal, wenn Sie die relevanten .pyc-Dateien nicht manuell löschen, da .pyc-Dateien beim Import verwendet werden können. Dies wird durch die Tatsache verstärkt, dass ein ordnungsgemäß konfiguriertes Versionskontrollsystem nur .py-Dateien in das zentrale Repository überträgt, nicht .pyc-Dateien, was bedeutet, dass Ihr Code den "Importtest" bestehen kann (funktioniert alles in Ordnung), einwandfrei und nicht Arbeit auf dem Computer eines anderen.
Zweitens können einige ziemlich schreckliche Fehler auftreten, wenn Sie Pakete in Module verwandeln. Wenn Sie ein Paket (einen Ordner mit einer
__init__.py
Datei) in ein Modul (eine .py-Datei) konvertieren, bleiben die .pyc-Dateien erhalten, die dieses Paket einmal dargestellt haben. Insbesondere die__init__.pyc
Überreste. Wenn Sie also das Paket foo mit einem Code haben, der keine Rolle spielt, löschen Sie das Paket später und erstellen Sie eine Datei foo.py mit einer Funktiondef bar(): pass
und führen Sie Folgendes aus:du erhältst:
weil Python immer noch die alten .pyc-Dateien aus dem foo-Paket verwendet, von denen keine die Leiste definiert. Dies kann besonders auf einem Webserver problematisch sein, auf dem vollständig funktionierender Code aufgrund von .pyc-Dateien beschädigt werden kann.
Aus diesen beiden Gründen (und möglicherweise aus anderen Gründen) sollten Ihr Bereitstellungscode und Ihr Testcode .pyc-Dateien löschen, z. B. mit der folgenden Bash-Zeile:
-B
Ab Python 2.6 können Sie Python auch mit dem Flag ausführen, um keine .pyc-Dateien zu verwenden. Siehe So vermeiden Sie .pyc-Dateien für mehr Details.Siehe auch: Wie entferne ich alle .pyc-Dateien aus einem Projekt?
quelle
__init__.py
Datei) konvertieren ...". Das wäre ein Paket, kein Modul.__init__.pyc
Überreste. - Woher? Da ein Paket ein Verzeichnis ist, bedeutet das Löschen eines Pakets das Löschen eines Verzeichnisses, sodass keine Dateien mehr vorhanden sind..pyc
Problem ist auch ein Grund: versteckte Abhängigkeiten von Betriebssystem- und Dienstprogramm-Patch-Levels,.so
Dateien, Konfigurationsdateien, anderen Python-Bibliotheken (wenn Sie nicht in einer virtuellen Umgebung ausgeführt werden), obskure Umgebungsvariablen ... die Liste geht weiter. Um gründlich zu sein und all diese Probleme zu finden, müssen Sie eine saubere Kopie Ihres Codes in einem Git-Repo erstellen oder als Paket auf einem PyPi-Server veröffentlichen und einen vollständigen Klon oder ein Setup auf einer neuen VM durchführen. Einige dieser potenziellen Probleme machen dieses.pyc
Problem im Vergleich blass.