Le bytecode python, ça existe ?

Le
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
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 4
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
yves
Le #1918917
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

Jean-Baptiste renard
Le #1920697
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.

Méta-MCI \(MVP\)
Le #1922446
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
Pierre Hanser
Le #1926901
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
Michel Claveau - NoSpam SVP ; merci
Le #1934362
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
Francois
Le #1934361
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

Francois
Le #1950655
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


pil91
Le #1957557
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.

Laurent Pointal
Le #1957556
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 -

Jean-Baptiste renard
Le #1957945
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.


Publicité
Poster une réponse
Anonyme