Pourquoi Python n'a-t-il pas besoin d'un compilateur?


29

Je me demande juste (maintenant que j'ai commencé avec C ++ qui a besoin d'un compilateur) pourquoi Python n'a pas besoin d'un compilateur?

Je viens de saisir le code, de l'enregistrer en tant qu'exécuteur et de l'exécuter. En C ++, je dois faire des builds et toutes ces autres choses amusantes.


4
Python n'est qu'un langage avec de nombreuses implémentations. Iron Python est compilé de la même manière que C # et C ++ est compilé, et il peut y avoir d'autres implémentations comme celle-ci.
Job

1
C # et C ++ ne sont pas compilés de la même manière - bien que vous puissiez affirmer qu'ils finissent tous les deux par des instructions machine, mais si vous le faites, vous pouvez dire que BASIC est également compilé de la même manière.
gbjbaanb

7
@gbjbaanb mais encore une fois l'anglais n'est pas compilé et l'analyse sémantique d'une phrase pourrait donner deux résultats tout aussi valides et ce qui précède pourrait être lu comme "iron python est compilé comme C # et C ++ est compilé"
Rune FS

Quelle plateforme / logiciel utilisez-vous pour écrire votre code Python? Si vous écrivez un fichier .py, ce n'est pas un exécutable. Il s'agit toujours d'un fichier de code source. À partir de la ligne de commande, vous utilisez la pythoncommande pour interpréter le fichier .py ou si vous utilisez IDLE ou Eclipse, l'EDI le fait pour vous.
Rick Henderson

Réponses:


68

Python a un compilateur! Vous ne le remarquez simplement pas car il s'exécute automatiquement. Vous pouvez cependant dire qu'il est là: regardez les fichiers .pyc(ou .pyosi l'optimiseur est activé) générés pour les modules que vous utilisez import.

En outre, il ne se compile pas dans le code de la machine native. Au lieu de cela, il compile en un code d'octet utilisé par une machine virtuelle. La machine virtuelle est elle-même un programme compilé. Ceci est très similaire à la façon dont Java fonctionne; si similaire, en fait, qu'il existe à la place une variante Python ( Jython ) qui se compile en code octet de la machine virtuelle Java! Il y a aussi IronPython , qui se compile en CLR de Microsoft (utilisé par .NET). (Le compilateur de code d'octet Python normal est parfois appelé CPython pour le dissocier de ces alternatives.)

C ++ doit exposer son processus de compilation car le langage lui-même est incomplet; il ne spécifie pas tout ce que l'éditeur de liens doit savoir pour construire votre programme, ni ne peut spécifier les options de compilation de manière portable (certains compilateurs vous permettent d'utiliser #pragma, mais ce n'est pas standard). Vous devez donc faire le reste du travail avec des makefiles et éventuellement auto hell (autoconf / automake / libtool). C'est vraiment juste un souvenir de la façon dont C l'a fait. Et C l'a fait de cette façon parce qu'il a rendu le compilateur simple, ce qui est l'une des principales raisons pour lesquelles il est si populaire (n'importe qui pouvait lancer un simple compilateur C dans les années 80).


Certaines choses qui peuvent affecter le fonctionnement du compilateur ou du lieur mais qui ne sont pas spécifiées dans la syntaxe C ou C ++:

  • résolution des dépendances
  • exigences de la bibliothèque externe (y compris l'ordre des dépendances)
  • niveau d'optimisation
  • paramètres d'avertissement
  • version de spécification de langue
  • mappages de l'éditeur de liens (quelle section va où dans le programme final)
  • architecture cible

Certains d'entre eux peuvent être détectés, mais ils ne peuvent pas être spécifiés; par exemple, je peux détecter avec quel C ++ est utilisé __cplusplus, mais je ne peux pas spécifier que C ++ 98 est celui utilisé pour mon code dans le code lui-même; Je dois le passer comme indicateur au compilateur dans le Makefile, ou faire un réglage dans une boîte de dialogue.

Bien que vous puissiez penser qu'un système de "résolution de dépendance" existe dans le compilateur, générant automatiquement des enregistrements de dépendance, ces enregistrements indiquent uniquement les fichiers d'en-tête utilisés par un fichier source donné. Ils ne peuvent pas indiquer quels modules de code source supplémentaires sont nécessaires pour se lier à un programme exécutable, car il n'existe aucun moyen standard en C ou C ++ d'indiquer qu'un fichier d'en-tête donné est la définition d'interface pour un autre module de code source par opposition à juste un tas de les lignes que vous souhaitez afficher à plusieurs endroits afin de ne pas vous répéter. Il existe des traditions dans les conventions de dénomination des fichiers, mais elles ne sont ni connues ni appliquées par le compilateur et l'éditeur de liens.

Plusieurs d'entre eux peuvent être définis à l'aide #pragma, mais ce n'est pas standard, et je parlais de la norme. Toutes ces choses pourraient être spécifiées par une norme, mais n'ont pas été dans l'intérêt de la compatibilité descendante. La sagesse qui prévaut est que les makefiles et les IDE ne sont pas cassés, alors ne les corrigez pas.

Python gère tout cela dans le langage. Par exemple, importspécifie une dépendance de module explicite, implique l'arborescence des dépendances et les modules ne sont pas divisés en en-têtes et fichiers sources (c'est-à-dire interface et implémentation).


3
L'implémentation C de Python est CPython , Cython est quelque chose de différent.
Greg Hewgill

4
Les autres raisons pour lesquelles C a été compilé en code machine étaient qu'il était destiné à être un assembleur glorifié, car les interprètes de bytecode étaient techniquement irréalisables sur le matériel dont ils disposaient et parce que l'une des tâches les plus importantes consistait à écrire un noyau de système d'exploitation.
tdammers

2
@BillyONeal avec la seule grande exception qu'en c / c ++, en tant que programmeur, vous devez faire des choses d'une certaine manière (soit faire des makefiles, soit vider tout dans le même blob) en python vous faites juste votre travail et le compilateur avec la VM s'occupe du reste
Rune FS

3
"C ++ doit exposer son processus de compilation car le langage lui-même est incomplet" Euh, quoi ??
Courses de légèreté avec Monica

3
Vous avez lu la partie juste après ça , non? "il ne spécifie pas tout ce que l'éditeur de liens doit savoir pour construire votre programme, ni ne peut spécifier les options de compilation de manière portative." Vous ne pouvez pas simplement créer un fichier C ++ en le nourrissant dans un compilateur; vous devez souvent fournir des métadonnées comme des drapeaux de compilation, inclure des chemins, etc. Ces métadonnées ne sont pas spécifiées par la norme et ne sont pas portables, c'est pourquoi nous devons faire glisser d'autres choses comme make, cmake, Visual Studio, ou quoi que ce soit pour finissez le travail. Ainsi, la norme doit appeler certaines choses comme dans l'unité de compilation et d'autres à l'échelle du programme.
Mike DeSimone

7

Python est un langage interprété. Cela signifie qu'il existe un logiciel sur votre ordinateur qui lit le code Python et envoie les "instructions" à la machine. L' article Wikipedia sur les langues interprétées pourrait être intéressant.

Lorsqu'un langage comme C ++ (un langage compilé) est compilé, cela signifie qu'il est converti en code machine pour être lu directement par le matériel lors de son exécution. L' article de Wikipedia sur les langues compilées pourrait fournir un contraste intéressant.


21
Il n'y a pas de langage interprété ou compilé. Une langue est un ensemble abstrait de règles mathématiques. Une langue n'est ni compilée ni interprétée. Une langue est juste . La compilation et l'interprétation sont des traits du compilateur ou de l'interprète (duh!), Pas de la langue. Chaque langue peut être implémentée avec un compilateur et chaque langue peut être implémentée avec un interprète. La plupart des langages ont à la fois compilé et interprété des implémentations. Il existe des interprètes pour C ++ et des compilateurs pour Python. (En fait, toutes les implémentations Python actuellement existantes ont des compilateurs.)
Jörg W Mittag

4
La majorité des implémentations de langage hautes performances modernes combinent à la fois un interprète et un compilateur (ou même plusieurs compilateurs) pour des performances maximales. En fait, il est impossible d'exécuter un programme sans interprète. Après tout, un compilateur n'est qu'un programme qui traduit un programme d'une langue dans une autre langue. Mais à un moment donné, vous devez réellement exécuter le programme, ce qui est fait par un interprète (qui peut ou non être implémenté dans le silicium).
Jörg W Mittag

10
@ JörgWMittag: Vous avez techniquement raison. Cependant, la plupart des langues ont été conçues pour un contexte interprété ou pour une compilation complète. Écrire un interpréteur pour GW BASIC ou Common Lisp est beaucoup plus facile que d'en écrire un pour, disons, C ++ ou C #; Python perd beaucoup de ses arguments de vente sans l'environnement interactif; écrire un compilateur pour PHP est sacrément difficile, et probablement horriblement inefficace, car l'exécutable compilé devrait contenir l'intégralité de l'interpréteur PHP, en raison de eval () et de constructions similaires - on pourrait affirmer qu'un tel compilateur tricherait.
tdammers

2
@tdammers, oui. Nous pouvons raisonnablement utiliser «langage compilé» pour signifier «langage habituellement compilé». Mais cela manque le point que PHP, Java, Python, Lua et C # sont tous implémentés en tant que compilateurs de bytecode. Toutes ces langues ont également implémenté JIT pour elles. Donc, vraiment, vous ne pouvez pas vraiment appeler certains de ces langages compilés et certains interprétés car ils ont la même stratégie de mise en œuvre.
Winston Ewert

2
@BillyONeal, pas vrai du moins pour python. Vous pouvez distribuer le bytecode python et l'exécuter sans la source. Mais il est vrai que vous ne pouvez pas distribuer python sans compilateur.
Winston Ewert

5

Toutes les langues compilées n'ont pas un cycle d'édition-compilation-lien-exécution en face à face.

Ce que vous rencontrez est une fonctionnalité / limitation de C ++ (ou au moins des implémentations C ++).

Pour faire quoi que ce soit, vous devez stocker votre code dans des fichiers et créer une image monolithique par un processus appelé liaison.

En particulier, c'est ce processus de liaison monolithique qui est confondu avec la distinction entre compilation et interprétation.

Certaines langues font tout cela de manière beaucoup plus dynamique, en éliminant l'étape de liaison monolithique maladroite, pas en éliminant la compilation en code machine. La source est toujours compilée en fichiers objet, mais ceux-ci sont chargés dans une image d'exécution, plutôt que liés dans un exécutable monolithique.

Vous dites "recharger ce module", et il charge la source et l'interprète, ou le compile, en fonction d'un commutateur de mode.

La programmation du noyau Linux a une partie de cette saveur même si vous travaillez en C. Vous pouvez recompiler un module et le charger et le décharger. Bien sûr, vous savez toujours que vous produisez quelque chose d'exécutable, et il est géré par un système de construction complexe, avec encore quelques étapes manuelles. Mais le fait est qu'à la fin, vous pouvez décharger et recharger juste ce petit module et ne pas avoir à redémarrer tout le noyau.

Certains langages ont une modularisation encore plus fine que celle-ci, et la construction et le chargement sont effectués à partir de leur temps d'exécution, de sorte qu'il est plus transparent.


2

quel détournement de la question initiale ... Un point non mentionné est que la source d'un programme python est ce que vous utilisez et distribuez, du point de vue de l'utilisateur c'est le programme. Nous avons tendance à simplifier les choses en catégories qui ne sont pas bien définies.

Les programmes compilés sont généralement considérés comme des fichiers autonomes de code machine. (il est vrai qu'il contient souvent des liens vers des bibliothèques de liens dynamiques associées à des systèmes d'exploitation spécifiques). Cela dit ... il existe des variantes de la plupart des langages de programmation qui pourraient être décrits comme compilés ou interprétés.

Python n'a pas besoin d'un compilateur car il s'appuie sur une application (appelée interprète) qui compile et exécute le code sans stocker le code machine en cours de création sous une forme que vous pouvez facilement accéder ou distribuer.


1

Tous les langages de programmation nécessitent la traduction de concepts humains en un code machine cible. Même le langage d'assemblage doit être traduit en code machine. Cette traduction se déroule généralement dans les phases suivantes:

Phase 1: Analyse et traduction (analyse) en un code intermédiaire. Phase 2: Traduction du code intermédiaire en code machine cible avec des espaces réservés pour les références externes. Phase 3: Résolution des références externes et du packaging dans un programme exécutable machine.

Cette traduction est souvent appelée pré-compilation et "Just in time" (JIT) ou compilation au moment de l'exécution.

Les langages tels que C, C ++, COBOL, Fortran, Pascal (pas tous) et Assembly sont des langages précompilés qui peuvent être exécutés directement par le système d'exploitation sans avoir besoin d'un interprète.

Des langages comme Java, BASIC, C # et Python sont interprétés. Ils utilisent tous ce code intermédiaire créé dans la phase 1, mais diffèrent parfois dans la façon dont ils le traduisent en code machine. Les formulaires les plus simples utilisent ce code intermédiaire pour exécuter des routines de code machine qui font le travail attendu. D'autres compileront le code intermédiaire en code machine et effectueront la correction des dépendances externes pendant l'exécution. Une fois compilé, il peut être immédiatement exécuté. De plus, le code machine est stocké dans un cache de code machine réutilisable précédemment compilé qui peut être réutilisé ultérieurement si la fonction est à nouveau nécessaire plus tard. Si une fonction a déjà été mise en cache, l'interpréteur n'a pas besoin de la recompiler.

La plupart des langages de haut niveau modernes entrent dans la catégorie interprétée (avec JIT). Ce sont surtout les langages plus anciens comme C & C ++ qui sont précompilés.

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.