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
yves
Le Sat, 29 Mar 2008 12:14:08 +0100, Francois a écrit:

Bonjour,

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 ?


Ca a l'air possible. Voici un petit exemple à essayer (en espèrant que ce
soit clair):

~/yves $ ls
maBibliotheque.py monProgramme.py

~/yves $ cat maBibliotheque.py
def f():
print "hello world"

if __name__ == "__main__":
f()

~/yves $ cat monProgramme.py
import maBibliotheque

print "voici la sortie de la fonction f:"
maBibliotheque.f()

~/yves $ python monProgramme.py
voici la sortie de la fonction f:
hello world

~/yves $ ls
maBibliotheque.py maBibliotheque.pyc monProgramme.py

~/yves $ rm maBibliotheque.py monProgramme.py

~/yves $ ls
maBibliotheque.pyc

~/yves $ python maBibliotheque.pyc
hello world

--
Yves

Avatar
Jean-Baptiste renard
Francois wrote:

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


oui, c'est exactement ça.

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 ?


oui, c'est possible mais ca n'a aucun intérêt.
le bytecode est stocké dans le fichier .pyc

quand tu fais python toto.py, l'interpréteur python regardera si il existe
déjà un toto.pyc. Si oui, il comparera les dates des 2 fichiers et si le
pyc est plus récent que le py, il prendra la version pyc, sinon, il va
compiler le toto.py pour faire un toto.pyc à jour.

Donc, au final tu gagne une comparaison de date entre le py et le pyc.
Bref, rien d'intéressant.

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

La fonction "compile()" est BUILTIN

Tu peux toujours compiler en mémoire, pour voir ce que ça donne.
Voici un exemple :

def ftemp( a, b):
r=a+b
return r

f='''def fmem( a, b):
r=a+b
return r
'''
ccod=compile( f, 'fonction:fmem', 'exec')
exec( ccod, globals(), globals())

print ftemp(2,3)
print fmem(2,3)

print ccod
print dir(ccod)


Autrement dit, on a compilé le code-source contenu dans la chaîne de
caractères "f", et obtenu, en réponse, l'objet-code "ccod".
Rien ne t'empêches de stocker tes morceaux de codes pré-compilés, pour
les utiliser où tu veux. C'est ce que fait Python, dans les fichiers
.pyc
AMHA, le principal gain, c'est la vérification syntaxique, qui est fait
au moment du "compile()", et n'est plus nécessaire pour "exec()"

@-salutations


Michel Claveau
Avatar
Pierre Hanser
par une coïncidence amusante, un article récent montre comment jouer
avec le bytecode:

http://pyside.blogspot.com/2008/03/ast-compilation-from-python.html
Avatar
Michel Claveau - NoSpam SVP ; merci
Bonsoir !

Coïncidence, certainement ; car j'utilise compile() depuis des années,
pour vérifier la syntaxe des codes-sources Python que je crée dans
Excel, Object-PAL, Autoit, ... (j'ai un serveur COM qui me permet
d'utiliser Python depuis la plupart des applications/langages de
Windows).

@-salutations

MCI
Avatar
Francois
Ca a l'air possible. Voici un petit exemple à essayer (en espèrant que ce
soit clair):


L'exemple marche, merci pour la réponse. Mais en fait, j'avoue ne pas
vraiment le comprendre (je débute).

a) Que font ces lignes exactement ?

if __name__ == "__main__":
f()

b) Pourquoi diable le fichier maBibliotheque.pyc
est-il créé lors de l'exécution de monProgramme.py ? Ça m'aurait moins
troublé que ce soit un fichier monProgramme.pyc qui soit créé, même si
sa création reste un peu mystérieuse pour moi (peut-être que la réponse
est dans le a) ?).

Merci encore.


François

Avatar
Francois
C'est possible de faire ça ?


oui, c'est possible mais ca n'a aucun intérêt.


Oui, je me doutais bien que ça n'avait pas d'intérêt. Je posais la
question uniquement par curiosité.

le bytecode est stocké dans le fichier .pyc

quand tu fais python toto.py, l'interpréteur python regardera si il existe
déjà un toto.pyc. Si oui, il comparera les dates des 2 fichiers et si le
pyc est plus récent que le py, il prendra la version pyc, sinon, il va
compiler le toto.py pour faire un toto.pyc à jour.

Donc, au final tu gagne une comparaison de date entre le py et le pyc.
Bref, rien d'intéressant.


Ok, merci pour ces explications très claires.

Si je comprends bien :

1) Quand je lance un toto.py sur mon ordinateur *pour la première fois*,
vu que le toto.pyc n'existe pas encore, Python le crée et le range dans
le dossier .pyc puis l'interpréteur interprète toto.pyc.
Dans ce cas, il y a eu "pré-compilation".

2) Quand je lance le même toto.py toujours sur mon ordinateur *pour la
deuxième fois*, vu que le toto.pyc existe avec la même date que toto.py,
l'interpréteur python interprète directement le toto.pyc déjà existant.
Dans ce cas, il n'y a pas eu "pré-compilation".

Mais cela veut-il donc dire qu'un premier lancement de programme (où il
y a pré-compilation) est toujours sensiblement plus long qu'un deuxième
lancement (où il n'y a pas de pré-compilation) ?

Merci pour la réponse.


François


Avatar
pil91
Cela doit être comme cela que procède Iddle pour la commande 'check
module.'
---------
j'utilise compile() depuis des années, pour vérifier la syntaxe des co des-sources Python que je crée dans
... Autoit, ...

MCI
------------

Tiens donc , est-ce une bonne voie pour crééer des utilitaires vites
fait, ou peut être même de petites applis, que le couple autoit +
python.
Désolé pour le hors sujet.

Avatar
Laurent Pointal
Le Sat, 29 Mar 2008 12:14:08 +0100, Francois a écrit :

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) ?


Voir http://docs.python.org/lib/module-dis.html



--
Laurent POINTAL -

Avatar
Jean-Baptiste renard
Francois wrote:

Tu as tout compris :)

un premier lancement de programme (où il
y a pré-compilation) est toujours sensiblement plus long qu'un deuxième
lancement (où il n'y a pas de pré-compilation) ?

oui, c'est un peu plus long.


1 2 3 4