Co to jest __pycache__?


651

Z tego, co rozumiem, pamięć podręczna jest zaszyfrowanym plikiem podobnych plików.

Co robimy z __pycache__folderem? Czy to jest to, co dajemy ludziom zamiast naszego kodu źródłowego? Czy to tylko moje dane wejściowe? Ten folder jest ciągle tworzony, do czego służy?


29
„Czy to jest to, co dajemy ludziom zamiast naszego kodu źródłowego?” - Nie, dajesz im kod źródłowy w ładnym, instalowalnym pakiecie, dzięki czemu jest łatwy w użyciu.
Lennart Regebro

79
Nikt jeszcze nie wspomniał, ale twoja definicja pamięci podręcznej jest dziwna. Pamięć podręczna jest po prostu składnikiem, który przechowuje dane, dzięki czemu przyszłe żądania dotyczące tych danych mogą być obsługiwane szybciej .
Ricardo Cruz,


1
Ponieważ Python 3.8możesz użyć zmiennej środowiskowej, aby zmienić lokalizację irytujących katalogów pamięci podręcznej: stackoverflow.com/a/57414308/1612318
Rotareti

Pamięć podręczna to coś, co przechowuje kopię rzeczy na wypadek, gdybyś jej potrzebował, abyś nie musiał wracać do oryginału, aby ją zdobyć. Został zaprojektowany tak, aby był szybszy niż przejście do pierwotnego miejsca. Może być szybszy, ponieważ nie musi wstępnie przetwarzać ani kompilować informacji. Lub może to być szybsze przechowywanie, np. Pamięć podręczna dysku w pamięci RAM lub pamięć podręczna sieci na dysku lokalnym. Z natury nie jest zaszyfrowany (chociaż czasem może być) i nie zawsze jest to „plik podobnych plików” - może to być plik, ładunek plików, blok pamięci RAM itp.
rjmunro

Odpowiedzi:


518

Po uruchomieniu programu w Pythonie interpreter najpierw kompiluje go do kodu bajtowego (jest to uproszczenie) i zapisuje go w __pycache__folderze. Jeśli tam zajrzysz, w folderze projektu znajdziesz kilka plików o wspólnych nazwach plików .py, tylko ich rozszerzenia będą w formacie .pyc lub .pyo. Są to odpowiednio skompilowane przez kod bajtowy wersje plików programu.

Jako programista możesz w dużej mierze po prostu zignorować ... Wszystko, co robi, to przyspieszyć uruchomienie programu. Gdy skrypty się zmienią, zostaną one ponownie skompilowane, a jeśli usuniesz pliki lub cały folder i uruchomisz program ponownie, pojawią się ponownie (chyba że wyraźnie powstrzymasz to zachowanie)

Jeśli używasz cpython (który jest najczęstszy, ponieważ jest to implementacja referencyjna) i nie chcesz tego folderu, możesz go wyłączyć, uruchamiając na przykład interpreter z flagą -B

python -B foo.py

Inną opcją, jak zauważył tcaswell, jest ustawienie zmiennej środowiskowej PYTHONDONTWRITEBYTECODEna dowolną wartość (zgodnie ze stroną podręcznika Pythona, dowolny „niepusty ciąg”).


48
Możesz także dodać zmienną środowiskową, PYTHONDONTWRITEBYTECODE=<any_value>aby trwale ją wyłączyć.
Mark Tolonen

11
Dla wyjaśnienia, dotyczy to tylko Pythona 3, prawda?
Joe J

11
@JoeJ tak, myślę, że to prawda. python2umieszcza skompilowane pliki w tym samym katalogu co oryginały, jeśli się nie mylę.
scott_fakename

27
Jednym WAŻNYM zastrzeżeniem jest to, że w przypadku braku pliku .py zostanie użyty buforowany plik .pyc zamiast pliku .py. W praktyce dzieje się tak tylko wtedy, gdy usuwasz (lub zmieniasz nazwę) moduły, więc nie jest to częste zdarzenie, ale jeśli jakieś rzeczy wciąż są „tam”, po podrapaniu się w głowę i uruchomieniu find. -nazwa * .pyc | xargs rm na twoim źródle jest prawdopodobnie dobrą pierwszą reakcją.
yacc143

34
find . -name '*.pyc' -deleteTak, find ma flagę do usuwania znalezionych plików, więc nie musisz używać żadnych shananiganów xargs
vlad-ardelean

174

__pycache__to folder zawierający kod bajtowy Pythona 3 skompilowany i gotowy do uruchomienia .

Nie polecam rutynowego usuwania tych plików lub tłumienia tworzenia podczas programowania, ponieważ może to obniżyć wydajność. Po prostu przygotuj komendę rekurencyjną (patrz poniżej), aby wyczyścić ją w razie potrzeby, ponieważ kod bajtowy może stać się przestarzały w przypadkach na krawędzi (patrz komentarze).

Programiści Python zwykle ignorują kod bajtowy. Rzeczywiście __pycache__i *.pycsą to wspólne linie do zobaczenia w .gitignoreplikach. Kod bajtowy nie jest przeznaczony do dystrybucji i można go zdemontować za pomocą dismodułu .


Jeśli korzystasz z systemu OS X, możesz łatwo ukryć wszystkie te foldery w projekcie, uruchamiając następujące polecenie z folderu głównego projektu.

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

Wymień __pycache__się *.pycdla Pythona 2.

Ustawia to flagę we wszystkich tych katalogach (plikach .pyc), informując Finder / Textmate 2 o wykluczeniu ich z listy. Co ważne, kod bajtowy jest tam ukryty.

Uruchom ponownie polecenie, jeśli tworzysz nowe moduły i chcesz ukryć nowy kod bajtowy lub jeśli usuwasz ukryte pliki kodu bajtowego.


W systemie Windows równoważne polecenie może być (nie testowane, mile widziane skrypty wsadowe):

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

To samo, co przeglądanie folderów projektu za pomocą kliknięcia prawym przyciskiem myszy> ukryj ...


Przeprowadzanie testów jednostkowych to jeden scenariusz (więcej w komentarzach), w którym usuwanie *.pycplików i __pycache__folderów jest rzeczywiście przydatne. Używam następujących wierszy ~/.bash_profilei po prostu biegam, claby wyczyścić w razie potrzeby.

alias cpy='find . -name "__pycache__" -delete'
alias cpc='find . -name "*.pyc"       -delete'
...
alias cl='cpy && cpc && ...'

Czy nie zostanie to cofnięte za każdym razem, gdy uruchomisz kod?
Holloway,

2
@DoTheEvo: po prostu się nie tworzy, więc przy następnym ładowaniu modułu nie ma przyspieszenia. Błąd nie jest zgłaszany.
Petr Viktorin

7
To nie jest dobra odpowiedź. Pytający chce wiedzieć, do czego służą te pliki. Ta odpowiedź mówi „nie przejmuj się tym”, a następnie powoduje, że znikają.
ciekawe,

36
Absolutnie kłopot się z ich usunięciem : nie jest to bezcelowe. Python z radością nie wykryje zmian w plikach i nie uruchomi pliku pamięci podręcznej w wielu okolicznościach, doprowadzając cię do szału z „dlaczego to nadal nie działa, zmieniłem kod, dlaczego nadal nie działa przy nieistniejących wywołaniach” nonsens. Szczególnie w środowiskach testowych najgorsze jest domyślnie „pycache”.
Mike „Pomax” Kamermans

2
Nie zgodziłbym się z tą radą, aby „nie zawracać sobie głowy usuwaniem tych plików” - widziałem to wielokrotnie, ostatnio przez „How To Python” Kennetha Reitza („sztuczka z kodem bajtowym”)
Louis Maddox

38

__pycache__Folder jest tworzony podczas korzystania z linii:

import file_name

lub spróbuj uzyskać informacje z innego utworzonego pliku. To sprawia, że ​​przy drugim uruchomieniu programu drugi plik jest nieco szybszy.


27

Zaktualizowana odpowiedź z dokumentów w wersji 3.7+:

Aby przyspieszyć ładowanie modułów, Python buforuje skompilowaną wersję każdego modułu w __pycache__katalogu pod nazwą module.version.pyc, gdzie wersja koduje format skompilowanego pliku; ogólnie zawiera numer wersji Pythona. Na przykład w CPython wydanie 3.3 skompilowana wersja spam.py będzie buforowana jako __pycache__/spam.cpython-33.pyc. Ta konwencja nazewnictwa pozwala na współistnienie skompilowanych modułów z różnych wydań i różnych wersji Pythona.

Źródło: https://docs.python.org/3/tutorial/modules.html#compiled-python-files

Oznacza to, że ten katalog jest generowany przez Python i istnieje, aby przyspieszyć działanie programów. Nie powinien być zaangażowany w kontrolę źródła i powinien współistnieć w zgodzie z lokalnym kodem źródłowym.


__pycache__to katalog zawierający pliki pamięci podręcznej kodu bajtowego, które są automatycznie generowane przez python, a mianowicie skompilowane .pycpliki python lub . Być może zastanawiasz się, dlaczego Python, język „interpretowany”, ma w ogóle jakieś skompilowane pliki. To SO pytanie dotyczy (i zdecydowanie warto przeczytać tę odpowiedź ).

Dokumenty Pythona są bardziej szczegółowe na temat tego, jak to działa i dlaczego istnieje:

  • Został on dodany w Pythonie 3.2, ponieważ istniejący system utrzymywania .pycplików w tym samym katalogu powodował różne problemy, na przykład podczas uruchamiania programu z interpreterami Pythona różnych wersji. Aby uzyskać pełną specyfikację funkcji, zobacz PEP 3174 .

5

z oficjalnego tutoriala Python Moduły

Aby przyspieszyć ładowanie modułów, Python buforuje skompilowaną wersję każdego modułu w __pycache__katalogu pod nazwą module.version.pyc, gdzie wersja koduje format skompilowanego pliku; ogólnie zawiera numer wersji Pythona. Na przykład w CPython wersja 3.6 skompilowana wersja spam.py będzie buforowana jako __pycache__/spam.cpython-36.pyc.

z Python doc Często zadawane pytania dotyczące programowania

Gdy moduł jest importowany po raz pierwszy (lub gdy plik źródłowy zmienił się od czasu utworzenia bieżącego pliku skompilowanego), plik pyc zawierający skompilowany kod powinien zostać utworzony w __pycache__podkatalogu katalogu zawierającego .pyplik. .pycPlik będzie miał nazwę pliku, który zaczyna się o tej samej nazwie co .pyplik, a kończy się .pyc, ze środkowego elementu, który zależy od konkretnego Pythona binarny, który go stworzył.


5

Wykonanie skryptu python spowodowałoby wygenerowanie kodu bajtowego w pamięci i zachowanie go do momentu zamknięcia programu. W przypadku importu modułu, w celu szybszego ponownego użycia, Python utworzy plik .pyc pamięci podręcznej (PYC to „skompilowana” wersja „Pythona”), w której buforowany jest kod bajtu importowanego modułu. Chodzi o to, aby przyspieszyć ładowanie modułów Pythona, unikając ponownej kompilacji (kompiluj raz, uruchamiaj zasady wielokrotnie) podczas ich ponownego importowania.

Nazwa pliku jest taka sama jak nazwa modułu. Część po początkowej kropce wskazuje implementację Pythona, która utworzyła pamięć podręczną (może to być CPython), a następnie jej numer wersji.


3

Interpreter Pythona kompiluje plik skryptu * .py i zapisuje wyniki kompilacji w __pycache__katalogu.

Gdy projekt zostanie ponownie wykonany, jeśli interpreter stwierdzi, że skrypt * .py nie został zmodyfikowany, pomija krok kompilacji i uruchamia wcześniej wygenerowany plik * .pyc zapisany w __pycache__folderze.

Gdy projekt jest złożony, możesz skrócić czas przygotowania do uruchomienia projektu. Jeśli program jest zbyt mała, można zignorować, że korzystając python -B abc.pyz tej Bopcji.


3

Python w wersji 2.x będzie miał .pyc, gdy interpreter skompiluje kod.

Python w wersji 3.x będzie miał __pycache__, gdy interpreter skompiluje kod.

alok@alok:~$ ls
module.py  module.pyc  __pycache__  test.py
alok@alok:~$

2

W wersji 3.2 i nowszych Python zapisuje skompilowane pliki kodu bajtowego .pyc w podkatalogu o nazwie __pycache__zlokalizowanym w katalogu, w którym znajdują się pliki źródłowe, z nazwami plików, które identyfikują wersję Pythona, która je utworzyła (np. Script.cpython-33.pyc)


Jak mogę uniknąć tworzenia folderu „ pycache ”, a wszystkie pliki .pyc powinny mieć taką samą nazwę jak plik .py?
Ashwani,

1

Po zaimportowaniu modułu ,

import file_name

Python przechowuje skompilowany kod bajtowy w __pycache__katalogu, aby przyszłe importy mogły z niego korzystać bezpośrednio, bez konieczności ponownego analizowania i kompilowania źródła.

Nie robi to tylko w celu uruchomienia skryptu, tylko podczas importowania pliku.

(Poprzednie wersje służyły do ​​przechowywania buforowanego kodu bajtowego jako plików .pyc, które zajmowały ten sam katalog co pliki .py, ale od wersji Python 3 zostały przeniesione do podkatalogu, aby uporządkować zawartość.)

PYTHONDONTWRITEBYTECODE ---> Jeśli jest ustawiony na niepusty ciąg, Python nie będzie próbował zapisywać plików .pyc podczas importu modułów źródłowych. Jest to równoważne z określeniem opcji -B.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.