Rozumiem, że pliki „.pyc” to skompilowane wersje zwykłych plików „.py”, tworzone w czasie wykonywania, aby programy działały szybciej. Zauważyłem jednak kilka rzeczy:
- Po modyfikacji plików „py” zachowanie programu zmienia się. Oznacza to, że pliki „py” są kompilowane lub przynajmniej przechodzą przez jakiś proces haszowania lub porównują znaczniki czasu w celu stwierdzenia, czy powinny zostać ponownie skompilowane.
- Po usunięciu wszystkich plików „.pyc” (
rm *.pyc
) czasami zmienia się zachowanie programu. Co oznaczałoby, że nie są one kompilowane przy aktualizacji plików „.py”.
Pytania:
- Jak decydują, kiedy mają być kompilowane?
- Czy istnieje sposób, aby zapewnić dokładniejsze sprawdzanie podczas opracowywania?
python
python-internals
pyc
Aaron Schif
źródło
źródło
rm *.pyc
. Nie spowoduje to usunięcia plików .pyc w zagnieżdżonych folderach. Użyjfind . -name '*.pyc' -delete
zamiast tegoOdpowiedzi:
Te
.pyc
pliki są tworzone (i ewentualnie nadpisane) tylko wtedy, gdy dany plik python jest importowany za pośrednictwem innego skryptu. Jeśli wywoływany jest import, Python sprawdza, czy.pyc
wewnętrzna sygnatura czasowa pliku nie jest starsza niż odpowiedni.py
plik. Jeśli tak, ładuje.pyc
; jeśli tak nie jest lub jeśli.pyc
jeszcze nie istnieje, Python kompiluje.py
plik do a.pyc
i ładuje go.Co masz na myśli mówiąc „ściślejsza kontrola”?
źródło
rm *.pyc
. Wiem, że jeśli wymuszę odtworzenie wszystkich plików, niektóre problemy zostaną naprawione, co oznacza, że pliki nie są ponownie kompilowane samodzielnie. Przypuszczam, że jeśli używają sygnatur czasowych, nie ma sposobu, aby zaostrzyć to zachowanie, ale problem nadal występuje..pyc
„s timestamp musi być starszy niż odpowiadająca.py
” s datownika do wyzwolenia rekompilacji.Pliki .pyc generowane za każdym razem, gdy odpowiednie elementy kodu są importowane i aktualizowane, jeśli odpowiednie pliki kodu zostały zaktualizowane. Jeśli pliki .pyc zostaną usunięte, zostaną automatycznie wygenerowane ponownie. Jednak nie są one automatycznie usuwane po usunięciu odpowiednich plików kodu.
Może to powodować naprawdę zabawne błędy podczas refaktorów na poziomie plików.
Po pierwsze, możesz skończyć z wypychaniem kodu, który działa tylko na twoim komputerze i na nikim innym. Jeśli masz wiszące odniesienia do usuniętych plików, będą one nadal działać lokalnie, jeśli nie usuniesz ręcznie odpowiednich plików .pyc, ponieważ pliki .pyc mogą być używane podczas importowania. Jest to potęgowane faktem, że odpowiednio skonfigurowany system kontroli wersji będzie przesyłać tylko pliki .py do centralnego repozytorium, a nie pliki .pyc, co oznacza, że Twój kod może przejść „test importu” (czy wszystko jest poprawnie importowane) po prostu dobrze i nie pracować na komputerze innej osoby.
Po drugie, możesz mieć całkiem okropne błędy, jeśli zamienisz pakiety w moduły. Gdy konwertujesz pakiet (folder z
__init__.py
plikiem) na moduł (plik .py), pliki .pyc, które kiedyś reprezentowały ten pakiet, pozostają. W szczególności__init__.pyc
szczątki. Tak więc, jeśli masz pakiet foo z jakimś kodem, który nie ma znaczenia, później usuń ten pakiet i utwórz plik foo.py z jakąś funkcjądef bar(): pass
i uruchom:from foo import bar
dostajesz:
ImportError: cannot import name bar
ponieważ python nadal używa starych plików .pyc z pakietu foo, z których żaden nie definiuje bar. Może to być szczególnie problematyczne na serwerze internetowym, gdzie całkowicie działający kod może się zepsuć z powodu plików .pyc.
W wyniku obu tych powodów (i być może innych) kod wdrożenia i kod testowy powinny usunąć pliki .pyc, takie jak następujący wiersz bash:
find . -name '*.pyc' -delete
Ponadto, począwszy od pythona 2.6, możesz uruchomić Pythona z
-B
flagą, aby nie używać plików .pyc. Zobacz Jak unikać plików .pyc? po więcej szczegółów.Zobacz też: Jak usunąć wszystkie pliki .pyc z projektu?
źródło
__init__.py
plikiem) ...”. To byłby pakiet, a nie moduł.__init__.pyc
szczątki. - Dlaczego? Ponieważ pakiet jest katalogiem, usunięcie pakietu oznacza usunięcie katalogu, więc nie ma już plików….pyc
problem jest również jednym z powodów: ukryte zależności od poziomów poprawek systemu operacyjnego i narzędzi,.so
plików , plików konfiguracyjnych, innych bibliotek Pythona (jeśli nie korzystasz z wirtualnego środowiska env), niejasne zmienne env ... lista jest długa. Aby być dokładnym i znaleźć wszystkie takie problemy, musisz zrobić czystą kopię swojego kodu w repozytorium git lub opublikować jako pakiet na serwerze w stylu PyPi i wykonać pełny klon lub konfigurację na nowej maszynie wirtualnej. Niektóre z tych potencjalnych problemów sprawiają, że ten.pyc
problem jest blady w porównaniu.