Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Le bytecode python, ça existe ?

34 réponses
Avatar
Francois
Bonjour à tous,

Dans un livre ("Apprendre à programmer avec Python" de Swinnen),
l'auteur explique (assez rapidement car ces questions ne sont vraiment
pas l'objet du livre) que Python serait une sorte de langage
intermédiaire entre "langage interprété"/"langage compilé". Il dit que
lorsqu'on fourni un source à Python:

1) Python commence à compiler le source en un code intermédiaire le
"bytecode", qui n'est pas un code exécutable directement, mais qui est
un code en langage machine (en binaire) et qui serait portable en plus.

2) Ensuite, c'est ce bytecode qui est interprété (par ... un
interpréteur) pour qu'il y ait exécution du programme. Comme le bytecode
est en langage machine, son interprétation est un peu plus rapide que
pour un langage interprété "classique", mais moins que pour un
exécutable binaire classique quand même.

a) Déjà, êtes vous d'accord avec tout ceci ? N'hésitez pas à me
rectifier la moindre imprécision (je trouve que c'est plus bénéfique).

b) Si tout cela est exact, alors est-il possible de récupérer le
bytecode d'un script quelconque (d'un simple hello world) ? Par exemple,
j'ai un script Python toto.py, je le "pré-compile" en toto.bytecode et
je peux lancer mon programme avec une commande du genre :

python toto.bytecode.

C'est possible de faire ça ?

Merci d'avance.


François

10 réponses

1 2 3 4
Avatar
Thierry B.
--{ Francois a plopé ceci: }--

En fait, la génération du bytecode ne se fait que lors de
l'importation d'un module, et pour _ce_ module. Jamais lors
de l'exécution directe d'un programme, pour le source de
ce programme. Mais si ce programme importe un module, ce
module sera bytecompilé à ce moment...


1) Ah ! C'est un élément nouveau ça. Un script toto.py n'est jamais
"byte-compilé" lors de son exécution. Mais alors, je suis un peu perdu,


En fait, je me suis peut-être mal expliqué, là... Dans "génération",
je parlais de l'écriture du résultat de la compilation dans un
fichier .pyc :)


--
En fait, ce qu'il est question de faire -- avec l'accord des modérateurs
de fur, cela va de soi --, c'est un [DOC] bisannuel qui récapitulerait les
3 [ÉTATS]. Mais on hésite sur le format.
Liquide avec bulles, ça le fait pas ?



Avatar
Méta-MCI \(MVP\)
Re !

Il doit donc être possible de faire à la volée une vérification
syntaxique


Ben oui-da.
Amuse-toi avec cet exemple :

import sys,traceback

f='''deeeeeeeeeeef fmem(a,b):
r=a+b
return r
'''
try:
ccod=compile(f,'fonction:fmem','exec')
flagcompile=True
except:
flagcompileúlse
print "Erreur syntaxiomatiquienne"
print "Type_erreur :",str(sys.exc_info()[0])
print "Erreur : ",str(sys.exc_info()[1])
tb=sys.exc_info()[2]
print str(sys.exc_info()[0]),traceback.format_exc()



@+

Michel Claveau

Avatar
Bruno Desthuilliers
Bonjour à tous,

Dans un livre ("Apprendre à programmer avec Python" de Swinnen),
l'auteur explique (assez rapidement car ces questions ne sont vraiment
pas l'objet du livre) que Python serait une sorte de langage
intermédiaire entre "langage interprété"/"langage compilé".


Je vais encore jouer les pédants, mais bon... Le fait d'être interprété
/ compilé en bytecode / compilé en code binaire "natif" n'est pas une
propriété d'un langage, mais d'une implémentation d'un langage.


Il dit que
lorsqu'on fourni un source à Python:

1) Python commence à compiler le source en un code intermédiaire le
"bytecode", qui n'est pas un code exécutable directement, mais qui est
un code en langage machine (en binaire) et qui serait portable en plus.


"langage machine" pour une machine qui n'existe en fait pas - et qu'on
appelle donc parfois "machine virtuelle" (pour d'autres langages en tous
cas - ici on est moins snob, on dit "interpréteur", même si ce n'est pas
tout à fait approprié).

2) Ensuite, c'est ce bytecode qui est interprété (par ... un
interpréteur) pour qu'il y ait exécution du programme. Comme le bytecode
est en langage machine, son interprétation est un peu plus rapide que
pour un langage interprété "classique", mais moins que pour un
exécutable binaire classique quand même.

a) Déjà, êtes vous d'accord avec tout ceci ?


Je ne sais pas si je suis "d'accord" ou pas, mais c'est effectivement
ainsi que fonctionnent les implémentations de Python actuellement
disponibles (CPython, Stackless et Pypy, qui utilisent le bytecode
spécifiquent à CPython, Jython qui utilise le bytecode Java, et
IronPython qui utilise le bytecode .NET).

N'hésitez pas à me
rectifier la moindre imprécision (je trouve que c'est plus bénéfique).

b) Si tout cela est exact, alors est-il possible de récupérer le
bytecode d'un script quelconque (d'un simple hello world) ? Par exemple,
j'ai un script Python toto.py, je le "pré-compile" en toto.bytecode


toto.pyc, en l'occurrence (si tu utilise CPython).

et
je peux lancer mon programme avec une commande du genre :

python toto.bytecode.

C'est possible de faire ça ?


Réponse courte : oui.

Réponse longue :

Pour ce qui est des modules, ils sont compilés au besoin par
l'interpréteur et sauvegardés dans des fichiers .pyc. Pour ce qui est
des scripts, ils sont ordinairement recompilés à chaque exécution, mais
tu peux forcer l'écriture du .pyc manuellement, cf

http://www.python.org/doc/current/lib/module-pycompile.html
http://www.python.org/doc/current/lib/module-compileall.html


Ceci étant, ce n'est pas forcément d'un intérêt foudroyant. Soit ton
script est un one-shot ou un utilitaire trivial et non critique, donc tu
te fiches de gagner quelques millisecondes au démarrage, soit c'est une
appli sérieuse, auquel cas le script servant de point d'entrée est
tellement minimaliste (typiquement: import d'un module et appel d'une
fonction de ce module) qu'il est plus rapide de le recompiler à chaque
exécution que de chercher un .pyc, comparer les dates etc...

Avatar
Laurent Pointal
Le Sun, 30 Mar 2008 19:36:32 +0200, Thierry B. a écrit :

--{ Francois a plopé ceci: }--

Je trouve ça étonnant que ce bytecode soit du binaire portable
(binaire + portable me semble plutôt incompatible). J'imagine que cette
procédure hybride entre la compilation et l'interprétation est une
chose "relativement moderne".


- Ce n'est pas du binaire au sens "code machine pour le vrai
processeur",
mais plutôt "code machine pour un processeur virtuel".

- Tout dépend de ton age :) pour le "relativement moderne". Si je me
souviens bien, il y avait déja quelques interpréteurs Basic qui
procédaient d'une manière équivalente dans les années 80. Je pense
au GFA Basic de l'Atari ST, entre autres...


Et le Pascal UCSD...

Cf google:
http://www.pascaland.org/historiq.htm
http://en.wikipedia.org/wiki/UCSD_Pascal
& Co...

--
Laurent POINTAL -


Avatar
Méta-MCI \(MVP\)
Bonjour !

Je vais encore jouer les pédants, mais bon... Le fait d'être
interprété / compilé en bytecode / compilé en code binaire "natif"
n'est pas une propriété d'un langage, mais d'une implémentation d'un
langage.


En fait, ton problème, c'est que tu crées beaucoup d'instances de ce
message (dans le sens contenu / sens profond), et que tu préfèrerais
qu'il y ait un singleton.

@+

MCI

Avatar
bruno.desthuilliers
On 31 mar, 18:39, "Méta-MCI (MVP)"
wrote:
Bonjour !

Je vais encore jouer les pédants, mais bon... Le fait d'être
interprété / compilé en bytecode / compilé en code binaire "nati f"
n'est pas une propriété d'un langage, mais d'une implémentation d' un
langage.


En fait, ton problème, c'est que tu crées beaucoup d'instances de ce
message (dans le sens contenu / sens profond), et que tu préfèrerais
qu'il y ait un singleton.


Ya de ça, en effet !-)


Avatar
bruno.desthuilliers
On 31 mar, 17:17, Francois wrote:
Ok, je pense que cette fois, c'est bon.

Je résume, j'espère ne pas dire trop de bêtises.

1) Un script Python qui n'est pas un module (un main.py), est bien sûr
byte-compilé pour être exécuté par la machine virtuelle (interpr éteur)
mais le fichier byte-code main.pyc résultant *n'est pas enregistré* su r
le disque dur. En quelque sorte, on peut dire, lors de son lancement,
qu'un script est byte-compilé "à la volée" et exécuté aussi sec par
l'interpréteur.


Yeps.


2) Pour un module (importé avec import). il est aussi byte-compilé pou r
être exécuté par la machine virtuelle (interpréteur) mais, par con tre,
le fichier byte-code module.pyc résultant *est enregistré* sur le disq ue
dur au même endroit que le module.


Yeps.

L'idée est qu'un module, «en
général», c'est un script qu'on ne va pas changer «trop souvent»


Mmm... Un module, c'est avant tout une bibliothèque d'objets
(fonctions, classes, etc) réutilisables. Après, bien sûr, on peut
avoir un .py qui soit utilisable à la fois comme programme et comme
module, mais c'est plus rare.

une
fois qu'il est «achevé». Donc on gagne un peu de temps


"un peu" ou plus, selon la taille du machin...

à le mettre au
préalable sous forme de byte-code.



3) On peut forcer un script main.py (qui n'est pas un module) à être
byte-compilé lors de son lancement


Un script (.py) est toujours compilé lors de son lancement. Ce qu'on
peut "forcer", c'est la sauvegarde de cette compilation dans un .pyc

pour avoir un byte-code tout fait, ce
qui peut éventuellement faire gagner un peu temps quand on exécute le
byte-code main.pyc directement. Mais :
a) Si le script est petit c'est dérisoire.
b) Si le script est énorme, cela ne serait peut-être pas
dérisoire, mais la philosophie serait alors de rendre
ce script petit en transférant le gros du script dans
des modules, dont le byte-code, quant à lui, sera bel
et bien enregistré dans le disque dur.

Est-ce correct ?


Globalement, oui.

Avatar
Francois
3) On peut forcer un script main.py (qui n'est pas un module) à être
byte-compilé lors de son lancement


Un script (.py) est toujours compilé lors de son lancement. Ce qu'on
peut "forcer", c'est la sauvegarde de cette compilation dans un .pyc


Zut ! Oui, oui, bien sûr. C'est ce que je voulais dire.


Est-ce correct ?


Globalement, oui.


Bon alors je me sens mieux. :-)

Merci beaucoup pour votre réponse.


François


Avatar
Thierry B.
--{ Laurent Pointal a plopé ceci: }--

- Tout dépend de ton age :) pour le "relativement moderne". Si je me
souviens bien, il y avait déja quelques interpréteurs Basic qui
procédaient d'une manière équivalente dans les années 80. Je pense
au GFA Basic de l'Atari ST, entre autres...


Et le Pascal UCSD...


Pour rester dans le ton du fil, j'ai un peu fait (p'taing, je suis
si vieux que ça ?) de l'UCSD sur Apple ][, et si je me souviens bien,
la phase de compilation était explicite.

http://www.pascaland.org/historiq.htm


Je vais aller lire, donc.


--
Who restarts those when they fail?
uggc://ra.jvxvcrqvn.bet/jvxv/Ovbybtvpny_ercebqhpgvba

But that's how we get all the lusers!

--{ from alt.sysadmin.recovery }--


Avatar
BertrandB
--{ Laurent Pointal a plopé ceci: }--

- Tout dépend de ton age :) pour le "relativement moderne". Si je me
souviens bien, il y avait déja quelques interpréteurs Basic qui
procédaient d'une manière équivalente dans les années 80. Je pense
au GFA Basic de l'Atari ST, entre autres...
Et le Pascal UCSD...



Pour rester dans le ton du fil, j'ai un peu fait (p'taing, je suis
si vieux que ça ?) de l'UCSD sur Apple ][, et si je me souviens bien,
la phase de compilation était explicite.

http://www.pascaland.org/historiq.htm


Je vais aller lire, donc.


c'était bien un compilateur et non pas un interpréteur.




1 2 3 4