Rendez votre package exécutable avec __main__.py


Tout le monde connait le fichier __init__.py, mais __main__.py est moins connu.

Il permet de lancer du code si on tente d’exécuter un package (c’est à dire un dossier qui contient un fichier __init__.py):

$ tree monpackage/
monpackakge/
├── __init__.py
└── __main__.py
 
0 directories, 2 files
$ cat monpackage/__main__.py
print('Hello :)')
$ python monpackage/ # ceci est un dossier 
Hello :)

Le __main__.py est aussi exécuté quand on fait python -m monpackage.

Notez que son exécution suppose l’import préalable du package, et que donc __init__.py sera toujours exécuté avant __main__.py. En revanche, faire juste import monpackage ne déclenche pas l’exécution de __main__.py.

Si vous zippez votre package et appelez la commande python, c’est aussi ce fichier qui sera exécuté. Pratique donc, pour faire un exécutable portable à peu de frais, tout en gardant la lib importable.

5 thoughts on “Rendez votre package exécutable avec __main__.py

  • cendrieR

    Tiens, c’est justement ce que je viens de faire chez moi, l’introduction de main.py. Comme ça j’ai un point d’entrée clair dans le package pour gérer les arguments en ligne de commande.

    À noter cependant qu’en python 2.* ça peut merder avec le module multiprocessing, juste à cause du nom “main.py”. Si je ne me trompe pas, il y a un bug patché uniquement en 3.* (je me suis fait avoir cette semaine) : http://bugs.python.org/issue10845.

  • Sam Post author

    Ca permet d’avoir la commande sans avoir à installer le module, ce qui est toujours pratique. Tout le monde a pas envie de se faire un setup.py, et un débutant peut parfois juste télécharger une archive sans vouloir (ou pouvoir) l’installer.

  • Yamakaky

    Concernant le module en zip, est ce qu’il y a une extension particulière, un peu comme les .jar ? Ce serait pratique pour que l’utilisateur n’ai pas à lancer python. J’ai trouvé ce pep, mais je ne sais pas s’il est appliqué (quelqu’un aurait-il une vm windows avec python 3.4 sous la main ?).

    https://www.python.org/dev/peps/pep-0441/

  • Symen

    @Yamakaky

    Alors d’après mes tests les fichiers .pyz et .pyzw ne sont associés à rien, mais renommer le zip en .py fonctionne ! (Même si ça ressemble à un gros hack)

    Par contre py.exe lancera le zip avec la version par défaut de python. Pour éviter ça, il suffit d’ajouter le shebang au début du fichier comme proposé pour les utilisateurs de UNIX dans la PEP-441 (que je ne connaissais pas).

  • Sam Post author

    Renommer en .py est acceptable. Apres tout si on utilise cette méthode de déploiement, c’est qu’on veut un truc quick and dirty. C’est ce que fait youtube-dl, et ça marche très bien.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.