Comment fonctionne Python Runtime?

26

J'ai quelques problèmes pour comprendre le concept de a runtime library, en particulier celui de Python. J'ai donc écrit un bon programme python et j'ai l'intention de l'exécuter, alors j'écris python ./hello_world.py.

Quelles étapes se produisent entre moi lorsque je clique sur le bouton Entrée et le code machine généré à partir de mon code python en cours d'exécution sur mon processeur? Et comment cela est-il lié au système d'exécution et / ou à la bibliothèque Python?

hgiesel
la source
Ces deux threads donnent un excellent aperçu du runtime Python - Python est-il interprété, ou compilé, ou les deux? & Python est-il interprété (comme Javascript ou PHP)? . La bibliothèque d'exécution et la bibliothèque d'exécution ne sont pas identiques. Le mapper au monde .NET que je connais - le Common Language Runtime (CLR) et Framework / Base Class Library (FCL / BCL) ne sont pas les mêmes.
RBT

Réponses:

33

Aussi divers soient-ils, il existe une poignée de concepts communs que tous les langages de programmation modernes et sérieux partagent. Deux d'entre eux sont au cœur de la réponse à vos questions ci-dessus.

Quelles étapes se produisent entre moi lorsque je clique sur le bouton Entrée et le code machine généré à partir de mon code python en cours d'exécution sur mon processeur?

Le code est analysé, analysé et introduit dans un interprète. Il s'agit d'un domaine très important de l'informatique connu sous le nom de théorie du compilateur . Un compilateur est un programme qui traduit du code d'une langue (votre code source) vers une autre langue (généralement du code machine, bien qu'il existe des "transpilers" qui traduisent d'une langue de haut niveau dans une autre). C'est un sujet vraiment énorme que vous pourriez passer des années à rechercher, mais voici la version de base:

Le compilateur commence par un analyseur , une routine qui lit votre code source et lui applique les règles de syntaxe du langage pour déterminer si cela a du sens en tant que code Python (dans votre cas) valide. Si ce n'est pas le cas, l'analyseur générera une erreur et le compilateur sortira, mais s'il le fait, l'analyseur génère ce que l'on appelle un arbre de syntaxe abstraite, ou AST pour faire court. L'AST est une structure de données arborescente dont les nœuds contiennent chacun un élément de la syntaxe. Par exemple, si vous dites x = 5, vous pourriez vous retrouver avec un BinaryExpressionnœud avec une operatorvaleur de =, une Leftvaleur de ReferenceExpression(x)et une Rightvaleur de IntegerLiteralExpression(5). Tout votre programme peut être représenté par un grand arbre comme celui-ci.

Une fois que l'analyseur produit un AST, la deuxième phase est l'analyse sémantique . En clair, cela signifie «comprendre ce que signifie cette AST». Il vérifie l'AST pour déterminer si vous avez fait quelque chose d'illégal même s'il s'agit d'une analyse valide (par exemple, essayer d'appeler une fonction à 1 argument avec 3 arguments) et génère des erreurs si vous le faites. Sinon, il analyse l'AST et y apporte des modifications pour le rendre plus simple à comprendre pour une machine.

La troisième phase est la génération de code. Une fois que vous avez un AST entièrement analysé, simplifié et valide, vous l'alimentez dans le générateur, qui parcourt l'AST et produit du code dans le langage de sortie. Ceci est votre produit fini.

Avec Python, il utilise un interpréteur plutôt qu'un compilateur. Un interpréteur fonctionne exactement de la même manière qu'un compilateur, à une différence près: au lieu de générer du code, il charge la sortie en mémoire et l'exécute directement sur votre système. (Les détails exacts de la façon dont cela se produit peuvent varier considérablement entre différentes langues et différents interprètes.)

Et comment cela est-il lié au système d'exécution et / ou à la bibliothèque Python?

Tous les langages, à l'exception des plus simples, sont livrés avec un ensemble de fonctions prédéfinies qui sont importantes pour un grand pourcentage d'utilisateurs et seraient difficiles à mettre en œuvre par les utilisateurs eux-mêmes pour une raison ou une autre. Leur code peut appeler ces fonctions sans avoir besoin de bibliothèques tierces. (Par exemple, en Python, vous avez print, qui envoie la sortie à stdout. Bonne chance pour l'implémentation par vous-même!) Cet ensemble de fonctions est généralement collecté dans une bibliothèque partagée que le code peut appeler au moment de l'exécution, c'est pourquoi il est connu comme la bibliothèque d'exécution de langue, ou simplement "le runtime" pour faire court.

Mason Wheeler
la source
Mon code est donc envoyé à un autre programme (le système d'exécution Python) qui fait tout cela et se termine à la fin de mon code (et après le nettoyage, bien sûr)?
hgiesel
@hgiesel Je crois que dans le cas de Python, l'interprète fait partie du runtime. Ce n'est pas le cas pour toutes les langues. bien sûr, mais c'est assez courant parmi les langues interprétées.
Mason Wheeler
5

L'implémentation Python standard est une machine virtuelle à code octet. Cela signifie que le code machine (opcodes de l'ensemble d'opcode de votre processeur) n'est pas généré à partir de votre programme. Les opcodes sont uniquement sélectionnés parmi les opcodes qui sont déjà compilés dans la machine virtuelle pendant que la VM interprète le code d'octet.

Comment votre programme est transformé en code octet en premier lieu est une question légèrement différente, mais la réponse courte est "grâce à la compilation, comme toute autre traduction de langue vers le bas".

Kilian Foth
la source