Question Si Python est interprété, que sont les fichiers .pyc?


On m'a donné à comprendre que Python est un langage interprété ... Cependant, quand je regarde mon code source Python, je vois .pyc fichiers, que Windows identifie comme "Compiled Python Files". Où viennent-ils?


796
2018-06-08 14:27


origine


Réponses:


Ils contiennent code d'octet, qui est ce que l'interpréteur Python compile la source. Ce code est ensuite exécuté par la machine virtuelle de Python.

La documentation de Python explique la définition comme ceci:

Python est un langage interprété, comme   opposé à un compilé, bien que le   la distinction peut être floue en raison de   la présence du compilateur bytecode.   Cela signifie que les fichiers source peuvent être   courir directement sans explicitement   créer un exécutable qui est alors   courir.


516
2018-06-08 14:28



On m'a donné à comprendre que   Python est un langage interprété ...

Ce mème populaire est incorrect, ou, plutôt, construit sur une incompréhension des niveaux de langage (naturels): une erreur similaire serait de dire "la Bible est un livre relié". Laissez-moi vous expliquer cette comparaison ...

"La Bible" est "un livre" dans le sens d'être un classe de (livres réels, objets physiques identifiés comme); les livres identifiés comme "copies de la Bible" sont censés avoir quelque chose de fondamental en commun (le contenu, même si ceux-ci peuvent être dans différentes langues, avec différentes traductions acceptables, niveaux de notes de bas de page et autres annotations). parfaitement bien permis de différer dans une myriade d'aspects qui sont ne pas considéré comme fondamental - type de reliure, couleur de la reliure, police (s) utilisée (s) dans l'impression, illustrations le cas échéant, grandes marges inscriptibles ou non, numéros et types de marque-pages intégrés, etc., et ainsi de suite.

Il est tout à fait possible qu'un typique l'impression de la Bible serait en effet reliée - après tout, c'est un livre qui est généralement destiné à être lu encore et encore, mis en signet à plusieurs endroits, feuilleté à la recherche de pointeurs de chapitre et de verset donnés, etc, etc, et une bonne reliure rigide peut rendre une copie donnée plus longtemps dans un tel usage. Cependant, ce sont des questions banales (pratiques) qui ne peuvent pas être utilisées pour déterminer si un objet de livre donné est une copie de la Bible ou non: les impressions de livres de poche sont parfaitement possibles!

De même, Python est "un langage" dans le sens de définir une classe de la langue implémentations qui doivent tous être similaires sur certains points fondamentaux (la syntaxe, la plupart des sémantiques sauf les parties de celles où ils sont explicitement autorisés à différer) mais sont autorisés à différer dans à peu près tous les détails de «mise en œuvre» - y compris la façon dont ils traitent les fichiers sources qui leur sont fournis, qu'ils compilent les sources dans des formulaires de niveau inférieur (et, le cas échéant, sous quelle forme - et qu'ils sauvegardent ces formulaires compilés, sur disque ou ailleurs), comment ils exécutent ces formulaires, etc. .

L'implémentation classique, CPython, est souvent appelée simplement "Python" - mais c'est juste une des nombreuses implémentations de qualité de production, à coté de IronPython de Microsoft (qui compile les codes CLR, ".NET"), Jython (qui se compile en codes JVM), PyPy (qui est écrit en Python lui-même et peut compiler à une grande variété de formes «back-end», y compris le langage machine généré juste-à-temps). Ils sont tous en Python (== "implémentations du langage Python") tout comme beaucoup d'objets de livres superficiellement différents peuvent tous être des Bibles (== "copies de la Bible").

Si CPython vous intéresse spécifiquement: il compile les fichiers source dans un formulaire de bas niveau spécifique à Python (appelé "bytecode"), le fait automatiquement en cas de besoin (lorsqu'il n'y a pas de fichier bytecode correspondant à un fichier source, ou le fichier bytecode est plus ancien que la source ou compilé par une version différente de Python), enregistre généralement les fichiers bytecode sur le disque (pour éviter de les recompiler dans le futur). OTOH IronPython compilera généralement aux codes CLR (les enregistrer sur le disque ou non, selon) et Jython aux codes JVM (les enregistrer sur le disque ou non - il utilisera le .class extension si cela les sauvegarde).

Ces formulaires de niveau inférieur sont ensuite exécutés par des «machines virtuelles» appropriées, également appelées «interprètes» - la machine virtuelle CPython, l'environnement d'exécution .Net, la machine virtuelle Java (ou JVM), selon le cas.

Donc, en ce sens (ce que font les implémentations typiques), Python est un "langage interprété" si et seulement si C # et Java sont: ils ont tous une stratégie d'implémentation typique de produire du bytecode, puis de l'exécuter via une VM / interprète .

Plus probablement, l'accent est mis sur la façon dont le processus de compilation est «lourd», lent et élevé. CPython est conçu pour être compilé aussi vite que possible, aussi léger que possible, avec aussi peu de cérémonie que possible - le compilateur fait très peu de vérification et d'optimisation des erreurs, donc il peut fonctionner rapidement et avec peu de mémoire, ce qui le laisse être exécuté automatiquement et de manière transparente chaque fois que nécessaire, sans que l'utilisateur n'ait besoin de savoir qu'une compilation est en cours, la plupart du temps. Java et C # acceptent généralement plus de travail lors de la compilation (et donc n'effectuent pas de compilation automatique) afin de mieux vérifier les erreurs et d'effectuer plus d'optimisations. C'est un continuum d'échelles de gris, pas une situation en noir ou blanc, et il serait totalement arbitraire de mettre un seuil à un niveau donné et de dire que seulement au-dessus de ce niveau vous l'appelez "compilation"! -)


779
2018-06-08 15:00



Il n'y a pas de langage interprété. Qu'il s'agisse d'un interpréteur ou d'un compilateur est purement un trait de la la mise en oeuvre et n'a absolument rien à voir avec la langue.

Chaque Le langage peut être implémenté soit par un interpréteur, soit par un compilateur. La grande majorité des langues ont au moins une implémentation de chaque type. (Par exemple, il existe des interpréteurs pour C et C ++ et des compilateurs pour JavaScript, PHP, Perl, Python et Ruby.) De plus, la majorité des implémentations de langage moderne combinent un interpréteur et un compilateur (ou même plusieurs compilateurs).

Une langue est juste un ensemble de règles mathématiques abstraites. Un interprète est l'une des stratégies de mise en œuvre concrètes d'une langue. Ces deux vivent sur des niveaux d'abstraction complètement différents. Si l'anglais était une langue typée, le terme "langage interprété" serait une erreur de type. L'affirmation "Python est un langage interprété" n'est pas seulement fausse (parce qu'être faux impliquerait que la déclaration a même un sens, même si elle est fausse), elle ne fait simplement pas sens, parce qu'une langue peut jamais être défini comme "interprété".

En particulier, si vous regardez les implémentations Python existantes, voici les stratégies d'implémentation utilisées:

  • IronPython: compile en arbres DLR que le DLR compile ensuite en bytecode CIL. Ce qui arrive au bytecode CIL dépend du CLI VES que vous utilisez, mais Microsoft .NET, GNU Portable.NET et Novell Mono finissent par le compiler en code machine natif.
  • Jython: interprète le code source Python jusqu'à ce qu'il identifie les chemins de code à chaud, qu'il compile ensuite vers le bytecode JVML. Ce qui arrive au bytecode JVML dépend de la JVM que vous utilisez. Maxine le compilera directement en code natif non optimisé jusqu'à ce qu'il identifie les chemins de code à chaud, qu'il recompile ensuite en code natif optimisé. HotSpot va d'abord interpréter le bytecode JVML, puis éventuellement compiler les chemins de code à chaud vers un code machine optimisé.
  • PyPy: compile en PyPy bytecode, qui est ensuite interprété par la machine virtuelle PyPy jusqu'à ce qu'elle identifie les chemins de code à chaud qu'elle compile ensuite en code natif, en bytecode JVML ou en bytecode CIL en fonction de la plate-forme utilisée.
  • CPython: compile en CPython bytecode qu'il interprète ensuite.
  • Python sans pile: compile en un bytecode CPython qu'il interprète ensuite.
  • Swallow à vide: compile en un bytecode CPython qu'il interprète ensuite jusqu'à ce qu'il identifie les chemins de code à chaud qu'il compile ensuite en LLVM IR que le compilateur LLVM compile ensuite en code machine natif.

Vous remarquerez peut-être que chacune des implémentations de cette liste (plus quelques autres que je n'ai pas mentionnées, comme tinypy, Shedskin ou Psyco) a un compilateur. En fait, pour autant que je sache, il n'y a actuellement aucune implémentation Python qui soit purement interprétée, il n'y a pas de telle implémentation planifiée et il n'y a jamais eu une telle implémentation.

Non seulement le terme "langage interprété" n'a pas de sens, même si vous l'interprétez comme signifiant "langage avec implémentation interprétée", ce n'est clairement pas vrai. Celui qui vous a dit ça, évidemment, ne sait pas de quoi il parle.

En particulier, .pyc Les fichiers que vous voyez sont des fichiers bytecode mis en cache par CPython, Stackless Python ou Unladen Swallow.


126
2018-06-08 15:25



Ceux-ci sont créés par l'interpréteur Python lorsqu'un .py le fichier est importé, et ils contiennent le "bytecode compilé" du module / programme importé, l'idée étant que la "traduction" du code source en bytecode (qui ne doit être fait qu'une seule fois) peut être ignorée à la suite imports si le .pyc est plus récent que le correspondant .py fichier, accélérant ainsi un peu le démarrage. Mais c'est toujours interprété.


55
2018-06-08 14:30



Python (au moins l'implémentation la plus courante) suit un modèle de compilation de la source d'origine en codes d'octets, puis interprète les codes d'octets sur une machine virtuelle. Cela signifie (encore une fois, l'implémentation la plus courante) n'est ni un pur interpréteur ni un compilateur pur.

De l'autre côté, cependant, le processus de compilation est principalement caché - les fichiers .pyc sont essentiellement traités comme un cache; ils accélèrent les choses, mais vous n'avez normalement pas à les connaître du tout. Il les invalide et les recharge automatiquement (recompile le code source) si nécessaire en fonction de l'horodatage du fichier.

La seule fois où j'ai vu un problème avec cela, c'est quand un fichier bytecode compilé a eu un horodatage dans le futur, ce qui signifiait qu'il avait toujours l'air plus récent que le fichier source. Comme il semblait plus récent, le fichier source n'a jamais été recompilé, donc peu importe les changements que vous avez faits, ils ont été ignorés ...


20
2018-06-08 15:01



C'est pour les débutants,

Python compile automatiquement votre script en code compilé, appelé code byte, avant de l'exécuter.

L'exécution d'un script n'est pas considérée comme une importation et aucun fichier .pyc ne sera créé.

Par exemple, si vous avez un fichier script abc.py qui importe un autre module xyz.py, quand tu cours abc.py, xyz.pyc sera créé car xyz est importé, mais aucun fichier abc.pyc ne sera créé puisque abc.py n'est pas importé.

Si vous devez créer un fichier .pyc pour un module qui n'est pas importé, vous pouvez utiliser le py_compile et compileall modules.

le py_compile module peut compiler manuellement n'importe quel module. Une façon est d'utiliser le py_compile.compile fonctionner dans ce module de manière interactive:

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

Cela écrira le fichier .pyc au même emplacement que abc.py (vous pouvez le remplacer par le paramètre facultatif cfile).

Vous pouvez également compiler automatiquement tous les fichiers dans un répertoire ou des répertoires en utilisant le module compileall.

python -m compileall

Si le nom du répertoire (le répertoire actuel dans cet exemple) est omis, le module compile tout ce qui se trouve sur sys.path


18
2017-11-03 06:47



Pour accélérer le chargement des modules, Python met en cache le contenu compilé des modules dans .pyc.

CPython compile son code source en "code octet", et pour des raisons de performances, il met en cache ce code d'octet sur le système de fichiers chaque fois que le fichier source a été modifié. Cela rend le chargement des modules Python beaucoup plus rapide car la phase de compilation peut être contournée. Lorsque votre fichier source est foo.py, CPython met en cache le code d'octet dans un fichier foo.pyc juste à côté de la source.

Dans python3, les machines d'import de Python sont étendues pour écrire et rechercher des fichiers cache de byte code dans un seul répertoire à l'intérieur de chaque répertoire de paquetages Python. Ce répertoire s'appellera __pycache__.

Voici un organigramme décrivant comment les modules sont chargés:

enter image description here

Pour plus d'informations:

ref:PEP3147
ref:Fichiers Python "compilés"


16
2017-07-11 17:04