Als Python wordt geïnterpreteerd, wat zijn dan .pyc-bestanden?

Ik heb geleerd te begrijpen dat Python een geïnterpreteerde taal is…
Als ik echter naar mijn Python-broncode kijk, zie ik .pyc-bestanden, die door Windows worden geïdentificeerd als “gecompileerde Python-bestanden”.

Waar komen deze binnen?


Antwoord 1, autoriteit 100%

Ze bevatten bytecode, waarnaar de Python-interpreter de broncode compileert. Deze code wordt vervolgens uitgevoerd door de virtuele machine van Python.

Python’s documentatie legt de definitie als volgt uit:

Python is een geïnterpreteerde taal, zoals
in tegenstelling tot een gecompileerde, hoewel de
onderscheid kan wazig zijn vanwege
de aanwezigheid van de bytecode-compiler.
Dit betekent dat bronbestanden kunnen worden
direct uitvoeren zonder expliciet
een uitvoerbaar bestand maken dat dan is
rennen.


Antwoord 2, autoriteit 97%

Ik heb geleerd dat te begrijpen
Python is een geïnterpreteerde taal…

Deze populaire meme is onjuist, of beter gezegd, gebaseerd op een verkeerd begrip van (natuurlijke) taalniveaus: een soortgelijke fout zou zijn om te zeggen “de Bijbel is een boek met harde kaft”. Laat me die vergelijking uitleggen…

“De Bijbel” is “een boek” in de zin van een klassevan (feitelijke, fysieke objecten geïdentificeerd als) boeken; de boeken die worden aangeduid als “kopieën van de Bijbel” zouden iets fundamenteels gemeen hebben (de inhoud, hoewel zelfs die in verschillende talen kunnen zijn, met verschillende aanvaardbare vertalingen, niveaus van voetnoten en andere annotaties) – die boeken zijn echter heel goed toegestaan om te verschillen in een groot aantal aspecten die nietals fundamenteel worden beschouwd — soort binding, kleur van binding, lettertype(s) gebruikt bij het drukken, eventuele illustraties, brede beschrijfbare marges of niet , nummers en soorten ingebouwde bladwijzers, enzovoort, enzovoort.

Het is heel goed mogelijk dat een typischeafdruk van de Bijbel inderdaad in hardcover gebonden zou zijn — het is tenslotte een boek dat typisch bedoeld is om keer op keer gelezen te worden, op verschillende plaatsen een bladwijzer te hebben, met een duim erop door te zoeken naar bepaalde hoofdstuk-en-vers-aanwijzingen, enz, enz., en een goede hardcover binding kan ervoor zorgen dat een bepaald exemplaar langer meegaat bij dergelijk gebruik. Dit zijn echter alledaagse (praktische) problemen die niet kunnen worden gebruikt om te bepalen of een bepaald boekobject een kopie van de Bijbel is of niet: paperback-drukken zijn perfect mogelijk!

Evenzo is Python “een taal” in de zin van het definiëren van een klasse van taal implementatiesdie allemaal in sommige fundamentele opzichten vergelijkbaar moeten zijn (syntaxis, de meeste semantiek behalve die delen daarvan waar ze expliciet mogen verschillen), maar mogen volledig verschillen in zowat elk “implementatie”-detail – inclusief hoe ze omgaan met de bronbestanden die ze krijgen, of ze de bronnen compileren naar een lager niveauformulieren (en, zo ja, welke vorm — en of ze dergelijke gecompileerde formulieren opslaan, op schijf of ergens anders), hoe ze die formulieren uitvoeren, enzovoort.

De klassieke implementatie, CPYTHON, wordt vaak slechts “Python” genoemd, maar het is slechts een van de implementaties van de productiekwaliteit, naast elkaar met Microsoft’s Ironpython (die op CLR-codes, ie, “.NET”. ), Jython (dat opstelt met JVM-codes), PYPY (die in Python zelf is geschreven en kan compileren op een enorme verscheidenheid aan “back-end” -formulieren, waaronder “Just-in-time” gegenereerde machinetaal). Ze zijn allemaal Python (== ‘implementaties van de Python-taal “) Net als veel oppervlakkig verschillende boekobjecten kunnen allemaal bijbels (==” exemplaren van de Bijbel “zijn).

Als u specifiek geïnteresseerd bent in CPYTHON: het compileert de bronbestanden in een Python-specifiek lager niveau (bekend als “bytecode”), doet dit automatisch wanneer dat nodig is (wanneer er geen bytecode-bestand is dat overeenkomt met een bron. Bestand, of het bypecode-bestand is ouder dan de bron of samengesteld door een andere Python-versie), slaat de bypecode-bestanden meestal op schijf (om deze in de toekomst te vermijden). Otoh Ironpython zal meestal compileren op CLR-codes (die ze opslaan op schijf of niet, afhankelijk) en Jython naar JVM-codes (opslaan op schijf of niet – het zal de .classextensie gebruiken als het wordt bespaard ze).

Deze formulieren met lagere niveau worden vervolgens uitgevoerd door geschikte “virtuele machines”, ook wel “tolken” genoemd – de CPYTHON VM, de .NET-runtime, de Java VM (aka JVM), indien van toepassing.

Dus in die zin (wat typische implementaties doen), is Python een “geïnterpreteerde taal” als en alleen als C # en Java zijn: ze hebben allemaal een typische implementatiestrategie om eerst Bytecode te produceren, en vervolgens via een Vm / tolk.

Het is waarschijnlijker dat de nadruk ligt op hoe “zwaar”, traag en ceremonieel het compilatieproces is. CPython is ontworpen om zo snel mogelijk te compileren, zo licht mogelijk, met zo min mogelijk ceremonie als mogelijk – de compiler doet heel weinig foutcontrole en optimalisatie, dus het kan snel en in kleine hoeveelheden geheugen werken, waardoor het op zijn beurt automatisch en transparant worden uitgevoerd wanneer dat nodig is, zonder dat de gebruiker zelfs maar hoeft te weten dat er meestal een compilatie aan de gang is. Java en C# accepteren doorgaans meer werk tijdens het compileren (en voeren daarom geen automatische compilatie uit) om fouten grondiger te controleren en meer optimalisaties uit te voeren. Het is een continuüm van grijstinten, geen zwart-witsituatie, en het zou volkomen willekeurig zijn om een drempel op een bepaald niveau te stellen en te zeggen dat je het pas boven dat niveau “compilatie” noemt!-)


Antwoord 3, autoriteit 27%

Er bestaat niet zoiets als een geïnterpreteerde taal. Of er een interpreter of compiler wordt gebruikt, is puur een eigenschap van de implementatieen heeft absoluut niets te maken met de taal.

Elketaal kan worden geïmplementeerd door een interpreter of een compiler. De overgrote meerderheid van de talen heeft ten minste één implementatie van elk type. (Er zijn bijvoorbeeld interpreters voor C en C++ en er zijn compilers voor JavaScript, PHP, Perl, Python en Ruby.) Bovendien combineren de meeste moderne taalimplementaties zowel een interpreter als een compiler (of zelfs meerdere compilers).

Een taal is slechts een verzameling abstracte wiskundige regels. Een tolk is een van de vele concrete implementatiestrategieën voor een taal. Die twee leven op totaal verschillende abstractieniveaus. Als Engels een getypte taal zou zijn, zou de term “geïnterpreteerde taal” een typefout zijn. De uitspraak “Python is een geïnterpreteerde taal” is niet alleen onwaar (omdat onwaar zou impliceren dat de verklaring zelfs maar logisch is, zelfs als deze verkeerd is), het is gewoon zinnig, omdat een taal kan nooitworden gedefinieerd als “geïnterpreteerd”.

In het bijzonder, als je kijkt naar de momenteel bestaande Python-implementaties, zijn dit de implementatiestrategieën die ze gebruiken:

  • IronPython: compileert naar DLR-bomen die de DLR vervolgens compileert naar CIL-bytecode. Wat er met de CIL-bytecode gebeurt, hangt af van de CLI VES waarop u draait, maar Microsoft .NET, GNU Portable.NET en Novell Mono zullen deze uiteindelijk compileren naar native machinecode.
  • Jython: interpreteert de Python-broncode totdat het de hot code-paden identificeert, die het vervolgens compileert naar JVML-bytecode. Wat er met de JVML-bytecode gebeurt, hangt af van de JVM waarop u draait. Maxine zal het direct compileren naar niet-geoptimaliseerde native code totdat het de hot code-paden identificeert, die het vervolgens opnieuw compileert naar geoptimaliseerde native code. HotSpot interpreteert eerst de JVML-bytecode en compileert uiteindelijk de hotcode-paden naar geoptimaliseerde machinecode.
  • PyPy: compileert naar PyPy-bytecode, die vervolgens wordt geïnterpreteerd door de PyPy VM totdat het de hotcode-paden identificeert die het vervolgens compileert in native code, JVML-bytecode of CIL-bytecode, afhankelijk van het platform waarop u draait.
  • CPython: compileert naar CPython-bytecode die het vervolgens interpreteert.
  • Stackless Python: compileert naar CPython-bytecode die het vervolgens interpreteert.
  • Unladen Swallow: compileert naar CPython-bytecode die het vervolgens interpreteert totdat het de hot-codepaden identificeert die het vervolgens compileert naar LLVM IR, die de LLVM-compiler vervolgens compileert naar native machinecode.
  • Cython: compileert Python-code naar draagbare C-code, die vervolgens wordt gecompileerd met een standaard C-compiler
  • Nuitka: compileert Python-code naar machine-afhankelijke C++-code, die vervolgens wordt gecompileerd met een standaard C-compiler

Het is je misschien opgevallen dat elk van de implementaties in die lijst (plus enkele andere die ik niet heb genoemd, zoals tinypy, Shedskin of Psyco) een compiler heeft. In feite is er, voor zover ik weet, momenteel geen Python-implementatie die puur wordt geïnterpreteerd, er is geen dergelijke implementatie gepland en er is nog nooit zo’n implementatie geweest.

Niet alleen is de term “geïnterpreteerde taal” niet logisch, zelfs als je het interpreteert als “taal met geïnterpreteerde implementatie”, is het duidelijk niet waar. Degene die je dat heeft verteld, weet duidelijk niet waar hij het over heeft.

Met name de .pyc-bestanden die u ziet, zijn bytecode-bestanden in de cache die zijn geproduceerd door CPython, Stackless Python of Unladen Swallow.


Antwoord 4, autoriteit 9%

Deze worden gemaakt door de Python-interpreter wanneer een .py-bestand wordt geïmporteerd, en ze bevatten de “gecompileerde bytecode” van de geïmporteerde module/het programma, waarbij het idee is dat de “vertaling” van de broncode code naar bytecode (wat maar één keer hoeft te gebeuren) kan worden overgeslagen bij volgende imports als de .pycnieuwer is dan de corresponderende .pybestand, waardoor het opstarten een beetje wordt versneld. Maar het wordt nog steeds geïnterpreteerd.


Antwoord 5, autoriteit 7%

Om het laden van modules te versnellen, slaat Python de gecompileerde inhoud van modules op in .pyc.

CPython compileert zijn broncode in “bytecode” en om prestatieredenen slaat het deze bytecode op in het bestandssysteem wanneer het bronbestand verandert. Dit maakt het laden van Python-modules veel sneller omdat de compilatiefase kan worden omzeild. Als uw bronbestand foo.py is, slaat CPython de bytecode op in een foo.pyc-bestand direct naast de bron.

In python3 is de importmachine van Python uitgebreid om cachebestanden met bytecode te schrijven en te zoeken in een enkele map binnen elke Python-pakketmap. Deze map heet __pycache__ .

Hier is een stroomschema dat beschrijft hoe modules worden geladen:

Voor meer informatie:

ref:PEP3147
ref:“Gecompileerde” Python-bestanden


Antwoord 6, autoriteit 6%

DIT IS VOOR BEGINNERS,

Python compileert uw script automatisch naar gecompileerde code, de zogenaamde bytecode, voordat het wordt uitgevoerd.

Het uitvoeren van een script wordt niet beschouwd als een import en er wordt geen .pyc gemaakt.

Als u bijvoorbeeld een scriptbestand abc.pyheeft dat een andere module xyz.pyimporteert, wanneer u abc.pyuitvoert , xyz.pycwordt gemaakt sinds xyz is geïmporteerd, maar er wordt geen abc.pyc-bestand gemaaktomdat abc.py niet wordt geïmporteerd.

Als u een .pyc-bestand moet maken voor een module die niet is geïmporteerd, kunt u de modules py_compileen compileallgebruiken.

De py_compileModule kan elke module handmatig samenstellen. Eén manier is om de py_compile.compile-functie in die module interactief te gebruiken:

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

Hierdoor wordt de .pique op dezelfde locatie als abc.py (u kunt dat overschrijven met de optionele parameter cfile).

U kunt ook automatisch alle bestanden in een map of directory’s compileren met behulp van de COMPILEALL-module.

python -m compileall

Als de mapnaam (de huidige map in dit voorbeeld) is weggelaten, stelt de module compileert alles gevonden op sys.path


Antwoord 7, Autoriteit 3%

Python (ten minste de meest voorkomende uitvoering ervan) volgt een patroon van het samenstellen van de oorspronkelijke bron naar bytecodes en interpreteert vervolgens de bytecodes op een virtuele machine. Dit betekent (opnieuw, de meest voorkomende implementatie) is noch een pure tolk noch een pure compiler.

De andere kant hiervan is echter dat het compilatieproces meestal verborgen is – de .pyc-bestanden worden in principe behandeld als een cache; Ze versnellen dingen, maar je hoeft normaal gesproken helemaal niet van bewust te zijn. Het is automatisch ongeldig en laadt ze opnieuw (compileert de broncode) indien nodig op basis van bestandstijd / datumstempels.

Over de enige keer dat ik hiermee een probleem heb gezien, was toen een gecompileerd bytecode-bestand op de een of andere manier een tijdstempel in de toekomst kreeg, wat betekende dat het altijd nieuwere leek dan het bronbestand. Omdat het er nieuw uitzag, werd het bronbestand nooit opnieuw gecompileerd, dus ongeacht welke veranderingen die u hebt gemaakt, ze werden genegeerd …


Antwoord 8, Autoriteit 2%

Python’s * .py-bestand is slechts een tekstbestand waarin u enkele regels code schrijft. Wanneer u dit bestand probeert uit te voeren met behulp van “Python Filename.py”

Deze opdracht roept Python Virtual Machine aan. Python Virtual Machine heeft 2 componenten: “Compiler” en “Interpreter”. Interpreter kan de tekst in * .py-bestand niet rechtstreeks lezen, dus deze tekst wordt eerst omgezet in een byte-code die is gericht op de PVM (niet hardware maar PVM) . Pvm voert deze bytecode uit. *. PYC-bestand wordt ook gegenereerd, als onderdeel van het uitvoeren van het uitvoering van uw importbewerking in het bestand in Shell of in een ander bestand.

Als dit * .pyc-bestand al is gegenereerd, dan wordt elke volgende keer dat u uw * .py-bestand uitvoert / uitvoert, wordt het systeem rechtstreeks uw * .pyc-bestand laadt dat geen compilatie nodig heeft (dit bespaart u enkele machinecycli van processor).

Nadat het * .pyc-bestand wordt gegenereerd, is er geen * .py-bestand nodig, tenzij u het bewerkt.


Antwoord 9

TLDR; Het is een geconverteerde code die de broncode vormt, die de Python VM interpreteert voor uitvoering.

Bottom-up begrip : de laatste fase van een programma is om de instructies van het programma op de hardware / machine uit te voeren / uit te voeren. Dus hier zijn de fasen voorafgaand aan de uitvoering:

  1. Uitvoering / draaien op CPU

  2. Bytcode converteren naar Machine Code .

    • Machine-code is de laatste fase van conversie.

    • Instructies Om te worden uitgevoerd op CPU, worden gegeven in de machinecode. Machinecode kan direct worden uitgevoerd door CPU.

  3. Converteren ByTecode naar Machine Code.

    • Bytecode is een middelgrote fase. Het kan worden overgeslagen voor efficiëntie , maar offeren draagbaarheid .
  4. Broncodeconverteren naar bytcode.

    • Broncode is een door mensen leesbarecode. Dit wordt gebruikt bij het werken aan IDE’s(code-editors) zoals Pycharm.

Nu de eigenlijke plot. Er zijn twee benaderingen bij het uitvoeren van een van deze fasen: converteer [of voer] een code in één keer uit (ook bekend als compileren) en converteer [of voer] de code regel voor regel uit (ook bekend als interpret).

  • We kunnen bijvoorbeeld een broncode compileren naar bytcoe, bytecode compileren naar machinecode, machinecode interpreteren voor uitvoering.

  • Sommige implementaties van talen slaan fase 3 over voor efficiëntie, d.w.z. compileren broncode in machinecode en interpreteren vervolgens machinecode voor uitvoering.

  • Sommige implementaties slaan alle middelste stappen over en interpreteren de broncode direct voor uitvoering.

  • Moderne talen hebben vaak te maken met zowel het samenstellen van een vertolking.

  • JAVA compileert bijvoorbeeld broncode naar bytcode [zo wordt JAVA-bron opgeslagen, als een bytcode], compileer bytcode naar machinecode [met behulp van JVM] en interpreteer machinecode voor uitvoering. [JVM wordt dus anders geïmplementeerd voor verschillende besturingssystemen, maar dezelfde JAVA-broncode kan worden uitgevoerd op verschillende besturingssystemen waarop JVM is geïnstalleerd.]

  • Python bijvoorbeeld, compileer broncode naar bytcode [meestal gevonden als .pyc-bestandenbij de .py-broncodes], compileer bytocde naar machinecode [gedaan door een virtuele machine zoals PVM en het resultaat is een uitvoerbaar bestand], interpreteer de machinecode/het uitvoerbare bestand voor uitvoering.

  • Wanneer kunnen we zeggen dat een taal wordt geïnterpreteerd of gecompileerd?

    • Het antwoord is door te kijken naar de aanpak die bij de uitvoering wordt gebruikt. Als het de machinecode in één keer uitvoert (== compileren), dan is het een gecompileerde taal. Aan de andere kant, als het de machinecode regel voor regel uitvoert (==interpreteren), dan is het een geïnterpreteerde taal.
  • Daarom zijn JAVA en Python geïnterpreteerde talen.

  • Er kan een verwarringoptreden vanwege de derde fase, namelijk het omzetten van bytcode naar machinecode. Vaak wordt dit gedaan met behulp van software die een virtuele machinewordt genoemd. De verwarring ontstaat omdat een virtuele machine zich als een machine gedraagt, maar dat is het eigenlijk niet! Virtuele machines zijn geïntroduceerd voor draagbaarheid, met een VM op een ECHTE machine kunnen we dezelfde broncode uitvoeren. De benadering die in de meeste VM’s wordt gebruikt [dat is de derde fase] is compileren, dus sommige mensen zouden zeggen dat het een gecompileerde taalis. Vanwege het belang van VM’s zeggen we vaak dat dergelijke talen zowel worden gecompileerd als geïnterpreteerd.


Antwoord 10

Pythoncode doorloopt 2 fasen. De eerste stap compileert de code in .pyc-bestanden, wat eigenlijk een bytecode is. Vervolgens wordt dit .pyc-bestand (bytecode) geïnterpreteerd met behulp van de CPython-interpreter. Raadpleeg dezelink. Hier wordt het proces van codecompilatie en -uitvoering in eenvoudige bewoordingen uitgelegd.


Antwoord 11

Machines begrijpen geen Engels of andere talen, ze begrijpen alleen bytecode, die ze moeten worden gecompileerd (bijv. C/C++, Java) of geïnterpreteerd (bijv. Ruby, Python), de .pyc is een gecachete versie van de bytecode.
https://www.geeksforgeeks.org/difference-between-compiled -and-interpreted-language/
Hier leest u snel wat het verschil is tussen gecompileerde taal en geïnterpreteerde taal. TLDR is een geïnterpreteerde taal, u hoeft niet alle code te compileren vóór de runtime en daarom zijn ze meestal niet streng op typen enz.

Other episodes