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.