On m'a donné à comprendre que Python est un langage interprété ...
Cependant, quand je regarde mon code source Python, je vois des .pyc
fichiers, que Windows identifie comme "Fichiers Python compilés".
D'où viennent-ils?
java
et javac
.
On m'a donné à comprendre que Python est un langage interprété ...
Cependant, quand je regarde mon code source Python, je vois des .pyc
fichiers, que Windows identifie comme "Fichiers Python compilés".
D'où viennent-ils?
java
et javac
.
Réponses:
Ils contiennent du code octet , ce à quoi 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é, par opposition à un langage compilé, bien que la distinction puisse être floue en raison de la présence du compilateur de bytecode. Cela signifie que les fichiers source peuvent être exécutés directement sans créer explicitement un exécutable qui est ensuite exécuté.
On m'a donné à comprendre que Python est un langage interprété ...
Ce mème populaire est incorrect, ou plutôt construit sur une mauvaise compréhension des niveaux de langage (naturel): une erreur similaire serait de dire "la Bible est un livre relié". Permettez-moi d'expliquer cette comparaison ...
"La Bible" est "un livre" dans le sens d'être une classe de livres (réels, 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 des traductions acceptables différentes, des niveaux de notes de bas de page et d'autres annotations) - cependant, ces livres sont parfaitement bien autorisé à différer dans une myriade d'aspects qui ne sont pas considérés comme fondamentaux - type de reliure, couleur de la reliure, police (s) utilisée (s) dans l'impression, illustrations le cas échéant, larges marges inscriptibles ou non, nombres et types de signets intégrés , et ainsi de suite.
Il est tout à fait possible qu'une impression typique de la Bible soit en effet sous reliure cartonnée - après tout, c'est un livre qui est généralement destiné à être lu à plusieurs reprises, mis en signet à plusieurs endroits, feuilleté à la recherche de pointeurs de chapitre et de versets donnés , etc, etc, et une bonne reliure cartonnée peut faire durer une copie donnée plus longtemps dans une telle utilisation. Cependant, ce sont des questions banales (pratiques) qui ne peuvent pas être utilisées pour déterminer si un objet de livre réel donné est une copie de la Bible ou non: des impressions de poche sont parfaitement possibles!
De même, Python est "un langage" dans le sens de définir une classe d' implémentations de langage qui doivent toutes être similaires à certains égards fondamentaux (syntaxe, la plupart des sémantiques sauf les parties de celles où elles sont explicitement autorisées à différer) mais sont entièrement autorisées pour différer dans à peu près tous les détails de "l'implémentation" - y compris la façon dont ils traitent les fichiers source qui leur sont fournis, s'ils compilent les sources dans des formulaires de niveau inférieur (et, si oui, quel formulaire - et s'ils enregistrent ces formulaires compilés, sur disque ou ailleurs), comment ils exécutent lesdits formulaires, etc.
L'implémentation classique, CPython, est souvent appelée simplement "Python" pour faire court - mais ce n'est qu'une des nombreuses implémentations de qualité de production, côte à côte avec IronPython de Microsoft (qui compile en codes CLR, c'est-à-dire ".NET"), Jython (qui se compile en codes JVM), PyPy (qui est écrit en Python lui-même et peut se compiler dans une grande variété de formes "back-end", y compris le langage machine généré "juste à temps"). Ce sont tous des Python (== "implémentations du langage Python") tout comme de nombreux objets de livres superficiellement différents peuvent tous être des Bibles (== "copies de La Bible").
Si vous êtes spécifiquement intéressé par CPython: il compile les fichiers source dans un formulaire de niveau inférieur spécifique à Python (connu sous le nom de "bytecode"), le fait automatiquement en cas de besoin (lorsqu'il n'y a pas de fichier de bytecode correspondant à un fichier source, ou le fichier de bytecode est plus ancien que la source ou compilé par une version différente de Python), enregistre généralement les fichiers de bytecode sur le disque (pour éviter de les recompiler à l'avenir). OTOH IronPython compilera généralement en codes CLR (en les enregistrant sur disque ou non, selon) et en Jython en codes JVM (en les enregistrant sur disque ou non - il utilisera l' .class
extension s'il les enregistre).
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, le runtime .Net, la machine virtuelle Java (alias JVM), selon le cas.
Donc, dans ce sens (que font les implémentations typiques), Python est un "langage interprété" si et seulement si C # et Java le sont: tous ont une stratégie d'implémentation typique de produire d'abord du bytecode, puis de l'exécuter via une VM / interprète .
Il est plus probable que l'accent soit mis sur la «lourdeur», la lenteur et la haute cérémonie du processus de compilation. CPython est conçu pour compiler aussi rapidement que possible, aussi léger que possible, avec aussi peu de cérémonie que possible - le compilateur effectue très peu de vérification et d'optimisation des erreurs, de sorte qu'il peut fonctionner rapidement et dans de petites quantités de mémoire, ce qui à son tour le permet être exécuté automatiquement et de manière transparente chaque fois que cela est nécessaire, sans que l'utilisateur ait même besoin de savoir qu'une compilation est en cours, la plupart du temps. Java et C # acceptent généralement plus de travail pendant la compilation (et n'effectuent donc pas de compilation automatique) afin de vérifier les erreurs plus en profondeur et d'effectuer plus d'optimisations. C'est un continuum d'échelles de gris, pas une situation en noir ou blanc,
Il n'y a pas de langage interprété. Qu'un interprète ou un compilateur soit utilisé est purement un trait de l' implémentation et n'a absolument rien à voir avec le langage.
Chaque langue peut être implémentée par un interprète ou un compilateur. La grande majorité des langues ont au moins une implémentation de chaque type. (Par exemple, il existe des interprètes pour C et C ++ et il existe des compilateurs pour JavaScript, PHP, Perl, Python et Ruby.) En outre, la majorité des implémentations de langage moderne combinent en fait à la fois un interprète et un compilateur (ou même plusieurs compilateurs).
Un langage n'est qu'un ensemble de règles mathématiques abstraites. Un interprète est l'une des nombreuses stratégies de mise en œuvre concrètes d'une langue. Ces deux-là vivent à des niveaux d'abstraction complètement différents. Si l'anglais était une langue dactylographiée, le terme «langue interprétée» serait une erreur de type. La déclaration "Python est un langage interprété" n'est pas seulement fausse (car être fausse impliquerait que la déclaration a même un sens, même si elle est erronée), elle n'a tout simplement aucun sens , car un langage ne peut jamais être défini comme "interprété."
En particulier, si vous regardez les implémentations Python actuellement existantes, ce sont les stratégies d'implémentation qu'elles utilisent:
Vous remarquerez peut-être que chacune des implémentations de cette liste (ainsi que d'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 purement interprétée, aucune implémentation de ce type n'est prévue 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 cela ne sait évidemment pas de quoi il parle.
En particulier, les .pyc
fichiers que vous voyez sont des fichiers de bytecode mis en cache produits par CPython, Stackless Python ou Unladen Swallow.
Ceux-ci sont créés par l'interpréteur Python lorsqu'un .py
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 effectuée qu'une seule fois) peut être ignoré sur les import
s suivants s'il .pyc
est plus récent que le .py
fichier correspondant , accélérant ainsi un peu le démarrage. Mais c'est toujours interprété.
Pour accélérer le chargement des modules, Python met en cache le contenu compilé des modules en .pyc.
CPython compile son code source en "code d'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 change. Cela accélère le chargement des modules Python 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.
En python3, la machinerie d'importation de Python est étendue pour écrire et rechercher des fichiers de cache de code octet dans un seul répertoire à l'intérieur de chaque répertoire de package Python. Ce répertoire sera appelé __pycache__.
Voici un organigramme décrivant comment les modules sont chargés:
Pour plus d'informations:
ref: PEP3147
ref: Fichiers Python "compilés"
C'EST POUR LES DÉBUTANTS,
Python compile automatiquement votre script en code compilé, appelé code d'octets, avant de l'exécuter.
L'exécution d'un script n'est pas considérée comme une importation et aucun .pyc ne sera créé.
Par exemple, si vous avez un fichier de script abc.py qui importe un autre module xyz.py , lorsque vous exécutez abc.py , xyz.pyc sera créé puisque xyz est importé, mais aucun fichier abc.pyc ne sera créé depuis 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 les modules py_compile
et compileall
.
Le py_compile
module peut compiler manuellement n'importe quel module. Une façon consiste à utiliser la py_compile.compile
fonction dans ce module de manière interactive:
>>> import py_compile
>>> py_compile.compile('abc.py')
Cela écrira le .pyc au même emplacement que abc.py (vous pouvez le remplacer avec le paramètre facultatif cfile
).
Vous pouvez également compiler automatiquement tous les fichiers d'un ou de plusieurs répertoires à l'aide du module compileall.
python -m compileall
Si le nom du répertoire (le répertoire courant dans cet exemple) est omis, le module compile tout ce qui se trouve sur sys.path
Python (au moins l'implémentation la plus courante de celui-ci) suit un modèle de compilation de la source d'origine en codes d'octets, puis d'interprétation des codes d'octets sur une machine virtuelle. Cela signifie (là encore, l'implémentation la plus courante) n'est ni un pur interprète ni un pur compilateur.
L'autre côté de ceci est, cependant, que le processus de compilation est principalement caché - les fichiers .pyc sont fondamentalement traités comme un cache; ils accélèrent les choses, mais vous n'avez normalement pas besoin d'en être conscients. Il les invalide automatiquement et les recharge (recompile le code source) si nécessaire en fonction des horodatages du fichier.
La seule fois où j'ai vu un problème avec cela, c'est quand un fichier de bytecode compilé a en quelque sorte un horodatage dans le futur, ce qui signifie qu'il a toujours l'air plus récent que le fichier source. Comme il avait l'air plus récent, le fichier source n'a jamais été recompilé, donc peu importe les modifications que vous avez apportées, il a été ignoré ...
Le fichier * .py de Python est juste un fichier texte dans lequel vous écrivez quelques lignes de code. Lorsque vous essayez d'exécuter ce fichier en utilisant, dites "python filename.py"
Cette commande appelle Python Virtual Machine. La machine virtuelle Python a 2 composants: "compilateur" et "interprète". L'interpréteur ne peut pas lire directement le texte dans le fichier * .py, donc ce texte est d'abord converti en un code d'octet qui est destiné au PVM (pas matériel mais PVM) . PVM exécute ce code d'octet. * Le fichier .pyc est également généré, dans le cadre de son exécution, qui effectue votre opération d'importation sur le fichier dans le shell ou dans un autre fichier.
Si ce fichier * .pyc est déjà généré, chaque fois que vous exécutez / exécutez votre fichier * .py, le système charge directement votre fichier * .pyc qui ne nécessite aucune compilation (cela vous fera économiser des cycles machine du processeur).
Une fois le fichier * .pyc généré, il n'est plus nécessaire d'avoir le fichier * .py, sauf si vous le modifiez.
Le code Python passe par 2 étapes. La première étape compile le code dans des fichiers .pyc qui est en fait un bytecode. Ensuite, ce fichier .pyc (bytecode) est interprété à l'aide de l'interpréteur CPython. Veuillez vous référer à ce lien. Ici, le processus de compilation et d'exécution de code est expliqué en termes simples.