Est-ce que Python est interprété, ou compilé, ou les deux?


190

D'après ma compréhension:

Un langage interprété est un langage de haut niveau exécuté et exécuté par un interpréteur (un programme qui convertit le langage de haut niveau en code machine puis s'exécute) en déplacement; il traite le programme petit à petit.

Un langage compilé est un langage de haut niveau dont le code est d'abord converti en code machine par un compilateur (un programme qui convertit le langage de haut niveau en code machine) puis exécuté par un exécuteur (un autre programme pour exécuter le code).

Corrigez-moi si mes définitions sont fausses.

Revenant maintenant à Python, je suis un peu confus à ce sujet. Partout, vous apprenez que Python est un langage interprété, mais il est interprété en un code intermédiaire (comme le byte-code ou IL) et non en le code machine. Alors, quel programme exécute le code IM? Veuillez m'aider à comprendre comment un script Python est géré et exécuté.



2
Python crée des fichiers .pyc (appelés byecode) chaque fois qu'une bibliothèque est importée. AFAIK le bytecode ne peut qu'accélérer les temps de chargement, pas les temps d'exécution.
Jesvin Jose

2
@aitchnyu: La mise en cache du bytecode dans les fichiers .pyc ne fait qu'accélérer le chargement, mais seulement parce que le code Python est compilé en bytecode avant l'exécution de toute façon. Bien que je ne pense pas que cela ait été essayé avec Python spécifiquement, d'autres implémentations de langage montrent que le bytecode est en effet plus facile à interpréter efficacement qu'un simple AST ou, pire encore, un code source non analysé. Les anciennes versions de Ruby interprétées à partir d'AST, par exemple, et AFAIK ont été un peu surpassées par les versions plus récentes qui compilent en bytecode.

Je ne veux pas paraître impoli, mais n'est-ce pas ce que je voulais dire (mais pas aussi informé que vous)?
Jesvin Jose

1
@aitchnyu: Je ne sais pas ce que vous vouliez dire. Je sais seulement que votre commentaire n'était pas incorrect mais offrait une bonne opportunité pour certaines informations de fond pourquoi il n'accélère que le temps de chargement, alors j'ai décidé d'ajouter ces informations. Aucune infraction

Réponses:


233

Tout d'abord, interprété / compilé n'est pas une propriété du langage mais une propriété de l'implémentation. Pour la plupart des langages, la plupart sinon toutes les implémentations tombent dans une seule catégorie, donc on peut économiser quelques mots en disant que le langage est également interprété / compilé, mais c'est toujours une distinction importante, à la fois parce que cela facilite la compréhension et parce qu'il y a pas mal de langues avec des implémentations utilisables des deux types (principalement dans le domaine des langages fonctionnels, voir Haskell et ML). En outre, il existe des interpréteurs et des projets C qui tentent de compiler un sous-ensemble de Python en code C ou C ++ (et ensuite en code machine).

Deuxièmement, la compilation ne se limite pas à une compilation anticipée vers le code machine natif. Un compilateur est, plus généralement, un programme qui convertit un programme dans un langage de programmation en un programme dans un autre langage de programmation (sans doute, vous pouvez même avoir un compilateur avec le même langage d'entrée et de sortie si des transformations importantes sont appliquées). Et les compilateurs JIT compilent en code machine natif au moment de l'exécution , ce qui peut donner une vitesse très proche voire meilleure que la compilation anticipée (en fonction du benchmark et de la qualité des implémentations comparées).

Mais pour arrêter de pinailler et répondre à la question que vous vouliez poser: Pratiquement (lire: en utilisant une implémentation quelque peu populaire et mature), Python est compilé . Non compilé en code machine à l'avance (c'est-à-dire «compilé» par la définition restreinte et erronée, mais hélas courante), «seulement» compilé en bytecode , mais c'est toujours une compilation avec au moins certains des avantages. Par exemple, l'instruction a = b.c()est compilée en un flux d'octets qui, lorsqu'il est "désassemblé", ressemble un peu à load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). C'est une simplification, c'est en fait moins lisible et un peu plus bas niveau - vous pouvez expérimenter avec le dismodule de bibliothèque standard et voir à quoi ressemble la vraie affaire.

Ce bytecode est soit interprété (notez qu'il y a une différence, à la fois en théorie et en performance pratique, entre l'interprétation directe et la première compilation vers une représentation intermédiaire et interpréter cela), comme avec l'implémentation de référence (CPython), ou à la fois interprété et compilé en code machine optimisé lors de l'exécution, comme avec PyPy .


2
Très bien, cela signifie qu'un script python est d'abord compilé en bytecode, puis il est implémenté par un interpréteur comme CPython, Jython ou IronPython etc.
Pankaj Upadhyay

19
Non, il est compilé en bytecode, puis le bytecode est exécuté par la VM respective. CPython est à la fois le compilateur et la VM, mais Jython et IronPython ne sont que le compilateur.
Ignacio Vazquez-Abrams

1
@Igacio: Je n'ai pas beaucoup d'expérience avec IronPython / Jython, mais au moins Jython ne fournit-il pas une couche de type interpréteur? Je ne pense pas qu'il soit possible d'essayer de transformer Python en bytecode JVM de type statique. Pourtant, bon point sur le compilateur et l'interpréteur faisant partie du même paquet.

2
+1 "... une propriété de l'implémentation". J'aurais moi-même dit "cela permet un shell interactif"
Jesvin Jose

2
@delnan: Eh bien, Jython agit comme une sorte d'intermédiaire entre le langage Python et la machine virtuelle Java, mais il compile en bytecode Java.
Ignacio Vazquez-Abrams

34

Le CPU ne peut en effet comprendre que le code machine. Pour les programmes interprétés, le but ultime d'un interpréteur est "d'interpréter" le code du programme en code machine. Cependant, généralement un langage interprété moderne n'interprète pas directement le code humain car il est trop inefficace.

L'interpréteur Python lit d'abord le code humain et l'optimise en un code intermédiaire avant de l'interpréter en code machine. C'est pourquoi vous avez toujours besoin d'un autre programme pour exécuter un script Python, contrairement à C ++ où vous pouvez exécuter directement l'exécutable compilé de votre code. Par exemple, c:\Python27\python.exeou /usr/bin/python.


11
J'aime le point sur "avoir besoin d'un autre programme pour l'exécuter". Cela a aidé à clarifier certaines de mes pensées.
Matt

donc python.exe optimise d'abord le code, puis l'interprète?
Koray Tugay

@KorayTugay, lorsque python.exe reçoit un code source de texte lisible par l'homme, il produit d'abord un octet de code optimisé, puis l'interprète (comme vous le dites); cependant, lorsqu'il existe déjà un fichier de code d'octet (pré-compilé), il n'a pas besoin de faire la première étape, ce qui permet de gagner du temps.
GordonBGood

31

La réponse dépend de l'implémentation de python utilisée. Si vous utilisez, disons CPython (l'implémentation standard de python) ou Jython (ciblé pour l'intégration avec le langage de programmation java), il est d'abord traduit en bytecode , et en fonction de l'implémentation de python que vous utilisez, ce bycode est dirigé vers le correspondant machine virtuelle pour l'interprétation . PVM (machine virtuelle Python) pour CPython et JVM (machine virtuelle Java) pour Jython.

Mais disons que vous utilisez PyPy, une autre implémentation standard de CPython. Il utiliserait un compilateur juste à temps .


Lors de la traduction en bytecode, il a besoin d'un compilateur, lequel est-ce?
RICKY

Pypy est une implémentation Python , pas une implémentation "CPython". En fait, Pypy est une alternative à CPython ( pypy.org/features.html ).
Giorgio

13

Selon le site officiel de Python, il s'agit d'un langage interprété.

https://www.python.org/doc/essays/blurb/

Python est un langage de programmation interprété, orienté objet et de haut niveau ...

...

Puisqu'il n'y a pas d'étape de compilation ...

...

L'interpréteur Python et la bibliothèque standard étendue sont disponibles ...

...

Au lieu de cela, lorsque l'interpréteur découvre une erreur, il déclenche une exception. Lorsque le programme n'attrape pas l'exception, l'interpréteur imprime une trace de pile.


7

Oui, c'est à la fois un langage compilé et interprété. Alors pourquoi nous l'appelons généralement comme langage interprété?

voir comment il est à la fois compilé et interprété?

Tout d'abord, je veux dire que vous aimerez davantage ma réponse si vous êtes du monde Java.

Dans Java, le code source est d'abord converti en code d'octet via le compilateur javac puis dirigé vers la JVM (responsable de la génération du code natif à des fins d'exécution). Maintenant, je veux vous montrer que nous appelons Java comme langage compilé car nous pouvons voir qu'il compile vraiment le code source et donne le .class fichier (rien que du bytecode) à travers:

javac Hello.java -------> produit le fichier Hello.class

java Hello --------> Diriger le bytecode vers JVM à des fins d'exécution

La même chose se produit avec python, c'est-à-dire que le code source est d'abord converti en bytecode via le compilateur puis dirigé vers le PVM (responsable de la génération du code natif à des fins d'exécution). Maintenant, je veux vous montrer que nous appelons généralement le Python comme un langage interprété parce que la compilation se produit dans les coulisses et lorsque nous exécutons le code python via:

python Hello.py -------> exécute directement le code et nous pouvons voir la sortie prouvée que le code est syntaxiquement correct

@ python Hello.py on dirait qu'il s'exécute directement mais en réalité il génère d'abord le bytecode qui est interprété par l'interpréteur pour produire le code natif à des fins d'exécution.

CPython - Prend la responsabilité de la compilation et de l'interprétation.

Regardez dans les lignes ci-dessous si vous avez besoin de plus de détails :

Comme je l'ai mentionné, CPython compile le code source mais la compilation réelle se produit avec l'aide de cython, puis l'interprétation se produit avec l'aide de CPython

Parlons maintenant un peu du rôle du compilateur Just-In-Time en Java et Python

Dans JVM, il existe un interpréteur Java qui interprète le bytecode ligne par ligne pour obtenir le code machine natif à des fins d'exécution, mais lorsque le bytecode Java est exécuté par un interpréteur, l'exécution sera toujours plus lente. Alors, quelle est la solution? la solution est le compilateur Just-In-Time qui produit le code natif qui peut être exécuté beaucoup plus rapidement que ce qui pourrait être interprété. Certains fournisseurs de JVM utilisent Java Interpreter et certains utilisent le compilateur Just-In-Time . Référence: cliquez ici

En python, pour contourner l'interpréteur pour obtenir une exécution rapide, utilisez une autre implémentation python ( PyPy ) au lieu de CPython . cliquez ici pour une autre implémentation de python, y compris PyPy .


6

Si (vous connaissez Java) {

le code Python est converti en bytecode comme le fait java.
Ce bytecode est exécuté à nouveau chaque fois que vous essayez d'y accéder.

} else {Le

code Python est initialement traduit en quelque chose appelé bytecode
qui est assez proche du langage machine mais pas du code machine réel
donc chaque fois que nous y accédons ou l'exécutons, ce bytecode est à nouveau exécuté

}


2

Presque, on peut dire que Python est un langage interprété. Mais nous utilisons une partie d'un processus de compilation ponctuel en python pour convertir le code source complet en code octet comme le langage Java.


1

Pour les débutants

Python compile automatiquement votre script en code compilé, appelé byte code, 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é.


1

C'est une grande confusion pour les personnes qui ont commencé à travailler sur python et les réponses ici sont un peu difficiles à comprendre, donc je vais vous faciliter la tâche.

Lorsque nous demandons à Python d'exécuter notre script, il y a quelques étapes que Python effectue avant que notre code ne commence réellement à se ressaisir:

  • Il est compilé en bytecode.
  • Ensuite, il est acheminé vers la machine virtuelle.

Lorsque nous exécutons un code source, Python le compile en un code octet. La compilation est une étape de traduction et le code d'octet est une représentation de bas niveau indépendante de la plate-forme du code source. Notez que le code d'octet Python n'est pas du code machine binaire (par exemple, des instructions pour une puce Intel).

En fait, Python traduit chaque instruction du code source en instructions de code d'octet en les décomposant en étapes individuelles. La traduction de code d'octet est effectuée pour accélérer l'exécution. Le code d'octet peut être exécuté beaucoup plus rapidement que les instructions de code source d'origine. Il a l'extension.pyc et il sera écrit s'il peut écrire sur notre machine.

Ainsi, la prochaine fois que nous exécuterons le même programme, Python chargera le fichier .pyc et sautera l'étape de compilation à moins qu'elle ne soit modifiée. Python vérifie automatiquement les horodatages des fichiers de code source et d'octet pour savoir quand il doit recompiler. Si nous réenregistrons le code source, le code d'octet est automatiquement créé à nouveau la prochaine fois que le programme est exécuté.

Si Python ne peut pas écrire les fichiers de code d'octet sur notre machine, notre programme fonctionne toujours. Le code d'octet est généré en mémoire et simplement rejeté à la sortie du programme. Mais comme les fichiers .pyc accélèrent le démarrage, nous pouvons vouloir nous assurer qu'il a été écrit pour des programmes plus volumineux.

Résumons ce qui se passe dans les coulisses. Lorsqu'un Python exécute un programme, Python lit le .py en mémoire, et l'analyse afin d'obtenir un bytecode, puis continue à s'exécuter. Pour chaque module importé par le programme, Python vérifie d'abord s'il existe une version de bytecode précompilée, dans un .pyo ou .pyc, qui a un horodatage qui correspond à son fichier .py. Python utilise la version bytecode le cas échéant. Sinon, il analyse le fichier .py du module, l'enregistre dans un fichier .pyc et utilise le bytecode qu'il vient de créer.

Les fichiers de code d'octet sont également un moyen d'envoyer des codes Python. Python exécutera toujours un programme s'il ne trouve que des fichiers.pyc, même si les fichiers source .py d'origine ne sont pas là.

Machine virtuelle Python (PVM)

Une fois que notre programme a été compilé en code octet, il est expédié pour être exécuté sur la machine virtuelle Python (PVM). Le PVM n'est pas un programme séparé. Il n'a pas besoin d'être installé par lui-même. En fait, le PVM est juste une grande boucle qui itère à travers notre instruction de code d'octet, un par un, pour effectuer leurs opérations. Le PVM est le moteur d'exécution de Python. Il est toujours présent dans le cadre du système Python. C'est le composant qui exécute vraiment nos scripts. Techniquement, ce n'est que la dernière étape de ce qu'on appelle l'interpréteur Python.


0

Le code python que vous écrivez est compilé en bytecode python, qui crée un fichier avec l'extension .pyc. Si compile, encore une fois la question est, pourquoi pas le langage compilé.

Notez qu'il ne s'agit pas d'une compilation au sens traditionnel du terme. En règle générale, nous dirions que la compilation utilise un langage de haut niveau et le convertit en code machine. Mais c'est une sorte de compilation. Compilé en code intermédiaire et non en code machine (j'espère que vous l'avez maintenant).

De retour au processus d'exécution, votre bytecode, présent dans le fichier pyc, créé à l'étape de compilation, est ensuite exécuté par les machines virtuelles appropriées, dans notre cas, la VM CPython. L'horodatage (appelé nombre magique) est utilisé pour valider si. py est modifié ou non, en fonction de la création du nouveau fichier pyc. Si pyc est du code actuel, il saute simplement l'étape de compilation.


0

Python (l'interpréteur) est compilé .

Preuve: il ne compilera même pas votre code s'il contient une erreur de syntaxe .

Exemple 1:

print("This should print") 
a = 9/0 

Production:

This should print
Traceback (most recent call last):
  File "p.py", line 2, in <module>
    a = 9/0
ZeroDivisionError: integer division or modulo by zero

Le code est compilé avec succès. La première ligne est exécutée ( print) La deuxième ligne est ZeroDivisionErrorlancée (erreur d'exécution).

Exemple 2:

print("This should not print")
/0         

Production:

  File "p.py", line 2
    /0
    ^
SyntaxError: invalid syntax

Conclusion : Si votre fichier de code ne contient SyntaxErrorrien, il s'exécutera car la compilation échouera.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.