Jeśli Python jest interpretowany, to czym są.pliki pyc?

Dano mi zrozumieć, że Python jest językiem interpretowanym... Jednak gdy patrzę na mój kod źródłowy Pythona, widzę .pyc pliki, które windows identyfikuje jako "skompilowane pliki Pythona". Gdzie to jest?

Author: rene, 2010-06-08

9 answers

Zawierają kod bajtowy , do którego interpreter Pythona kompiluje źródło. Kod ten jest następnie wykonywany przez maszynę wirtualną Pythona.

Dokumentacja Pythona wyjaśnia definicję w następujący sposób:

Python jest językiem interpretowanym, jako w przeciwieństwie do skompilowanego, choć rozróżnienie może być rozmyte ze względu na obecność kompilatora kodu bajtowego. Oznacza to, że pliki źródłowe mogą być Uruchom bezpośrednio bez jawnie tworzenie wykonywalny, który jest wówczas uciekaj.

 537
Author: unwind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-08 14:28:40

I ' ve been given to understand that Python jest językiem interpretowanym...

Ten popularny mem jest niepoprawny, lub raczej zbudowany na niezrozumieniu (naturalnych) poziomów językowych: podobnym błędem byłoby stwierdzenie"Biblia jest książką w twardej oprawie". Pozwól mi wyjaśnić to podobieństwo...

"Biblia" jest "księgą" w tym sensie, że jest klasą (rzeczywistych, fizycznych przedmiotów identyfikowanych jako) księgi; księgi identyfikowane jako "kopie Biblii" mają aby mieć coś wspólnego fundamentalnego ( treść, chociaż nawet te mogą być w różnych językach, z różnymi akceptowalnymi tłumaczeniami, poziomami przypisów i innych adnotacji) - jednak te książki są całkowicie dozwolone, aby różnić się niezliczoną ilością aspektów, które nie są uważane za fundamentalne-rodzaj oprawy, kolor oprawy, czcionki używane w druku, ilustracje, jeśli istnieją, szerokie marginesy do zapisu lub nie, Liczby i rodzaje wbudowanych zakładek itp. naprzód.

Jest całkiem możliwe, że typowe drukowanie Biblii byłoby rzeczywiście w twardej oprawie - w końcu jest to książka, która jest zazwyczaj przeznaczona do czytania w kółko, zakładki w kilku miejscach, miniaturki poprzez szukanie poszczególnych rozdziałów i wersetów, itd., itd., a dobre oprawa w twardej oprawie może sprawić, że dana kopia będzie trwać dłużej w takim użyciu. Są to jednak kwestie przyziemne (praktyczne), których nie można wykorzystać do ustalenia, czy dany rzeczywisty obiekt książki jest Kopia Biblii czy nie: wydruki w miękkiej oprawie są całkowicie możliwe!

Python jest językiem, w którym można zdefiniować klasę implementacji języka które muszą być podobne pod pewnymi fundamentalnymi względami (składnia, większość semantyki z wyjątkiem tych części, w których wyraźnie mogą się różnić), ale są w pełni dozwolone, aby różnić się w prawie każdym" implementacji " szczegółów - w tym, jak radzą sobie z plikami źródłowymi, które są podane, czy kompilują źródła do niektórych formularzy niższego poziomu (a jeśli tak, to w jakiej formie-i czy zapisują takie skompilowane formularze, na dysk czy gdzie indziej), jak wykonują te formularze, i tak dalej. [2]} klasyczna implementacja, CPython, jest często nazywana po prostu" Pythonem "w skrócie-ale jest to tylko jedna z kilku implementacji o jakości produkcyjnej, obok Microsoft IronPython (który kompiluje do kodów CLR, tj.". NET"), Jython (który kompiluje do kodów JVM), PyPy (który jest napisany w języku Python sam i może kompilować do ogromnej różnorodności "back-endowych" form, w tym" just-In-time " wygenerowanego języka maszynowego). Wszystkie one są Pythonem (=="implementacje języka Python"), podobnie jak wiele powierzchownie różnych obiektów książkowych może być Biblią (=="kopie Biblii").

Jeśli interesuje Cię konkretnie CPython: kompiluje pliki źródłowe do specyficznej dla Pythona postaci niższego poziomu( znanej jako "bytecode"), robi to automatycznie, gdy jest to potrzebne (gdy nie ma pliku bajtowego odpowiadający plikowi źródłowemu lub plik bajtowy jest starszy od źródła lub skompilowany przez inną wersję Pythona), Zwykle zapisuje pliki bajtowe na dysk (aby uniknąć ich ponownej kompilacji w przyszłości). OTOH IronPython zazwyczaj kompiluje się do kodów CLR (zapisując je na dysku lub nie, w zależności od tego), a Jython do kodów JVM (zapisując je na dysku lub nie -- użyje rozszerzenia .class, jeśli je zapisze).

Te formularze niższego poziomu są następnie wykonywane przez odpowiednie " maszyny wirtualne" znane również jako" interpretery " - VM CPython, środowisko uruchomieniowe.Net, VM Java (aka JVM), odpowiednio.

Tak więc, w tym sensie (co robią typowe implementacje), Python jest "językiem interpretowanym" wtedy i tylko wtedy, gdy C# i Java są: wszystkie z nich mają typową strategię implementacji, polegającą na wytwarzaniu najpierw kodu bajtowego, a następnie wykonywaniu go za pomocą maszyny wirtualnej/interpretera.

Bardziej prawdopodobne jest skupienie się na tym, jak "ciężki", powolny i wysoki jest proces kompilacji. CPython jest przeznaczony do kompilacji jako szybki jak to możliwe, tak lekki jak to możliwe, z tak małą ceremonią jak to możliwe-kompilator robi bardzo mało sprawdzania i optymalizacji błędów, dzięki czemu może działać szybko i w małych ilościach pamięci, co z kolei pozwala na automatyczne i przejrzyste uruchamianie w razie potrzeby, bez potrzeby nawet uświadamiania sobie, że przez większość czasu trwa kompilacja. Java i C# zazwyczaj akceptują więcej pracy podczas kompilacji (a zatem nie wykonują automatycznej kompilacji) w celu dokładniej sprawdzaj błędy i wykonuj więcej optymalizacji. Jest to kontinuum szarych skal, a nie czarno-biała sytuacja, i byłoby całkowicie arbitralne postawić próg na danym poziomie i powiedzieć, że tylko powyżej tego poziomu, który nazywasz "kompilacją"!-)

 809
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-12 16:50:12

Nie ma czegoś takiego jak język interpretowany. To, czy używany jest interpreter czy kompilator, jest wyłącznie cechą implementacji i nie ma absolutnie nic wspólnego z tym językiem.

Każdy język może być zaimplementowany przez interpreter lub kompilator. Zdecydowana większość języków posiada co najmniej jedną implementację każdego typu. (Na przykład istnieją interpretery dla C i C++ oraz Kompilatory dla JavaScript, PHP, Perl, Python i Ruby.) Poza tym większość współczesnych implementacji języka w rzeczywistości łączy zarówno interpreter, jak i kompilator (lub nawet wiele kompilatorów).

Język jest tylko zbiorem abstrakcyjnych reguł matematycznych. Tłumacz jest jedną z kilku konkretnych strategii wdrażania danego języka. Ci dwaj żyją na zupełnie innych poziomach abstrakcji. Jeśli język angielski byłby językiem typowanym, termin "język interpretowany" byłby błędem typu. Stwierdzenie " Python jest interpretowany język " nie jest po prostu fałszywy (ponieważ bycie fałszywym oznacza, że stwierdzenie ma nawet sens, nawet jeśli jest błędne), to po prostu nie ma sensu , ponieważ język może nigdy być zdefiniowany jako "interpretowany."

W szczególności, jeśli spojrzeć na aktualnie istniejące implementacje Pythona, są to strategie implementacji, których używają:

  • IronPython: kompiluje do drzew DLR, które DLR następnie kompiluje do kodu bajtowego CIL. Co się dzieje z CIL bytecode zależy od tego na którym CLI Ves jesteś uruchomiony, ale Microsoft. NET, GNU Portable.NET a Novell mono ostatecznie skompiluje go do natywnego kodu maszynowego.
  • Jython: interpretuje kod źródłowy Pythona, dopóki nie zidentyfikuje gorących ścieżek kodu, które następnie kompiluje do kodu bajtowego jvml. To, co stanie się z kodem bajtowym JVML, zależy od tego, na którym JVM jest uruchomiony. Maxine skompiluje go bezpośrednio do nie zoptymalizowanego kodu natywnego, dopóki nie zidentyfikuje gorących ścieżek kodu, do których następnie przekompiluje zoptymalizowany kod natywny. HotSpot najpierw zinterpretuje kod bajtowy JVML, a następnie kompiluje ścieżki hot code do zoptymalizowanego kodu maszynowego.
  • PyPy: kompiluje do kodu bajtowego PyPy, który następnie jest interpretowany przez maszynę wirtualną PyPy, dopóki nie zidentyfikuje ścieżek gorącego kodu, które następnie kompiluje do kodu natywnego, kodu bajtowego JVML lub kodu CIL w zależności od platformy, na której jesteś uruchomiony.
  • CPython: kompiluje do kodu bajtowego CPython, który następnie interpretuje.
  • Stackless Python: kompiluje do kodu bajtowego CPython, który następnie interpretuje.
  • Unladen Swallow: kompiluje do bajtowego kodu CPython, który następnie interpretuje, dopóki nie zidentyfikuje gorących ścieżek kodu, które następnie kompiluje do LLVM IR, które kompilator LLVM kompiluje do natywnego kodu maszynowego.

Możesz zauważyć, że każda z implementacji na tej liście (plus kilka innych, o których nie wspomniałem, jak tinypy, Shedskin czy Psyco) ma kompilator. Faktycznie, z tego co wiem, obecnie nie ma Implementacja Pythona, która jest czysto interpretowana, nie ma takiej implementacji zaplanowanej i nigdy nie było takiej implementacji.

Termin "język interpretowany" nie tylko nie ma sensu, nawet jeśli interpretuje się go jako "język z interpretowaną implementacją", ale jest wyraźnie nieprawdziwy. Ktokolwiek ci to powiedział, najwyraźniej nie wie, o czym mówi.

W szczególności, pliki .pyc, które widzisz, są buforowanymi plikami bajtowymi wyprodukowanymi przez CPython, Pyton bez stosu lub Jaskółka bez ładunku.

 130
Author: Jörg W Mittag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-04 17:15:38

Są one tworzone przez interpreter Pythona, gdy importowany jest plik .py i zawierają " skompilowany bajt kodu "zaimportowanego modułu/programu, przy czym" tłumaczenie " z kodu źródłowego na bajt kodu (które musi być wykonane tylko raz) może być pominięte w kolejnych importS, Jeśli .pyc jest nowszy niż odpowiedni plik .py, co przyspiesza nieco uruchomienie. Ale to nadal jest interpretowane.

 55
Author: Tim Pietzcker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-08 14:35:35

TO JEST DLA POCZĄTKUJĄCYCH,

Python automatycznie kompiluje skrypt do skompilowanego kodu, tak zwanego kodu bajtowego, przed uruchomieniem go.

Uruchomienie skryptu nie jest uważane za import i nie .zostanie utworzony pyc.

Na przykład, jeśli Masz plik skryptu abc.py importuje inny moduł xyz.py , kiedy biegniesz abc.py, xyz.pyc zostanie utworzony, ponieważ XYZ jest importowany, ale nie ma abc.plik pyc zostanie utworzony od abc.py nie jest importowany.

Jeśli chcesz utworzyć .plik pyc dla modułu, który nie jest importowany, możesz użyć modułów py_compile i compileall.

Moduł py_compile może ręcznie skompilować dowolny moduł. Jednym ze sposobów jest interaktywne użycie funkcji py_compile.compile w tym module:

>>> import py_compile
>>> py_compile.compile('abc.py')

To napisze .pyc do tego samego miejsca co abc.py (możesz to nadpisać opcjonalnym parametrem cfile).

Można również automatycznie skompilować wszystkie pliki w katalogu lub katalogi za pomocą modułu compileall.

python -m compileall

Jeśli nazwa katalogu (bieżący katalog w tym przykładzie) jest pominięta, moduł kompiluje wszystko, co znajduje się na sys.path

 23
Author: MAX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-12 10:08:45

Aby przyspieszyć ładowanie modułów, Python buforuje skompilowaną zawartość modułów w .pyc.

CPython kompiluje swój kod źródłowy do "kodu bajtowego" i ze względu na wydajność, buforuje ten kod bajtowy w systemie plików za każdym razem, gdy plik źródłowy ulegnie zmianie. To sprawia, że ładowanie modułów Pythona jest znacznie szybsze, ponieważ można ominąć fazę kompilacji. Gdy plik źródłowy jest foo.py , CPython buforuje kod bajtowy w foo.plik pyc obok źródła.

W python3, Python ' s import machinery jest rozszerzony do zapisu i wyszukiwania plików pamięci podręcznej kodu bajtowego w jednym katalogu wewnątrz każdego katalogu pakietów Pythona. Ten katalog będzie się nazywał _ _ pycache__.

Oto schemat opisujący sposób ładowania modułów:

Tutaj wpisz opis obrazka

Więcej informacji:

Ref: PEP3147
ref: "skompilowane" pliki Pythona

 21
Author: hxysayhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 17:04:09

Python (przynajmniej najczęstsza jego implementacja) podąża za wzorcem kompilacji oryginalnego źródła do kodów bajtowych, a następnie interpretacji kodów bajtowych na maszynie wirtualnej. Oznacza to, że (ponownie, najczęstsza implementacja) nie jest ani czystym interpreterem, ani czystym kompilatorem.

Druga strona jest jednak taka, że proces kompilacji jest w większości Ukryty -- the .pliki pyc są w zasadzie traktowane jak pamięć podręczna; przyspieszają wszystko, ale zwykle nie musisz być świadomy w ogóle. Automatycznie unieważnia i ponownie ładuje je (ponownie kompiluje kod źródłowy) w razie potrzeby na podstawie znaczników czasu/daty Pliku.

O jedyny raz widziałem problem z tym było, gdy skompilowany plik bajtowy jakoś dostał znacznik czasu dobrze w przyszłości, co oznaczało, że zawsze wyglądał nowszy niż plik źródłowy. Ponieważ plik źródłowy wyglądał na nowszy, nigdy nie został przekompilowany, więc bez względu na wprowadzone zmiany były ignorowane...

 20
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-08 15:01:16

Plik*. PY Pythona jest tylko plikiem tekstowym, w którym zapisuje się kilka linii kodu. Gdy próbujesz wykonać ten plik za pomocą powiedz "python filename.py"

To polecenie wywołuje maszynę wirtualną Pythona. Wirtualna maszyna Pythona posiada 2 komponenty: "kompilator" i "interpreter". Interpreter nie może odczytać bezpośrednio tekstu w pliku*. py, więc ten tekst jest najpierw konwertowany do kodu bajtowego, który jest kierowany do PVM (nie sprzętowego, ale PVM) . PVM wykonuje ten kod bajtowy. *.plik pyc jest również generowany, w ramach jego uruchomienia, który wykonuje operację importu na pliku w powłoce lub w innym pliku.

Jeśli to *.plik pyc jest już wygenerowany, a następnie przy każdym następnym uruchomieniu/wykonaniu pliku *.py system ładuje bezpośrednio Twój plik *.plik pyc, który nie będzie wymagał żadnej kompilacji (pozwoli to zaoszczędzić kilka cykli maszynowych procesora).

Raz *.plik pyc jest generowany, nie ma potrzeby pliku *. py, chyba że go edytujesz.

 10
Author: Vishal Mopari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-26 02:30:33

Kod Pythona przechodzi przez 2 etapy. Pierwszy krok kompiluje kod do .pliki pyc, które w rzeczywistości są bajtowym kodem. Potem to .plik pyc (kod bajtowy) jest interpretowany za pomocą interpretera CPython. Proszę odnieść się do Ten link. Tutaj proces kompilacji i wykonywania kodu jest wyjaśniony w prosty sposób.

 7
Author: Tango,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-26 06:41:47