Outils personnels
Vous êtes ici : Accueil Python Bonnes pratiques et astuces Python Les packages et modules

Les packages et modules

Par David Goodger - Dernière modification 17/05/2008 11:23
Contributeurs : David Larlet
CC BY-SA

Importer

from module import *

Vous avez probablement déjà vu cette manière de faires des imports avec une "étoile". Vous l'appréciez peut-être. Ne l'utilisez pas.

Pour paraphraser un exemple très connu :

LUKE: Est-ce que from module import * est meilleur que des imports explicites ?
YODA: Non, pas meilleur. Plus rapide, plus simple, plus séduisant.
LUKE: Mais comment saurais-je pourquoi les imports explicites sont meilleurs que les formes étoilées ?
YODA: Tu sauras lorsque ton code dans 6 mois tu essayeras de lire.

Les imports étoilés sont le mauvais côté de la Force en Python.

Les imports de type from module import * polluent votre espace de nom. Vous allez avoir des choses que vous n'attendiez pas. Vous pouvez avoir des conflits avec les noms que vous avez défini localement. Vous n'allez plus savoir d'où viennent certains noms. Bien que ce soit un raccourci pratique, ça ne doit pas arriver en production.

Morale : n'utilisez pas d'imports étoilés !

Il est bien meilleur de référencer les noms à partir de leurs modules :

import module
module.name

importer un module avec un nom plus court si nécessaire (avec alias) :

import long_module_name as mod
mod.name

ou importer juste les noms dont vous avez besoin de manière explicite :

from module import name
name

Notez qu'il est nécessaire d'utiliser "reload()" sur un module lorsque vous utilisez le prompt interactif si vous éditez celui-ci.

Modules et scripts

Pour faire à la fois un module importable et un script exécutable :

if __name__ == '__main__':
    # script code here

Lorsqu'il est importé, un attribut__name__ est setté, correspondant au nom du fichier du module, sans ".py". Le code ci-dessus ne va donc pas être lancé lors d'un import. Lorsqu'il est lancé comme un script, l'attribut __name__ est setté à "main" et le script va être exécuté.

Excepté pour certains cas spéciaux, vous ne devriez placer aucun code important au plus haut niveau. Placez votre code dans des fonctions, classes, méthodes et protégez le avec if __name__ == '__main__'.

Structure d'un module

"""module docstring"""

# imports
# constants
# exception classes
# interface functions
# classes
# internal functions & classes

def main(...):
    ...

if __name__ == '__main__':
    status = main()
    sys.exit(status)

C'est la façon dont un module devrait être structuré.

Packages

package/
    __init__.py
    module1.py
    subpackage/
        __init__.py
        module2.py
  • Utilisés pour organiser un projet.
  • Réduisent le nombre d'entrées lors du chargement.
  • Réduisent les conflits en cas d'imports.

Exemple :

import package.module1
from packages.subpackage import module2
from packages.subpackage.module2 import name

En Python 2.5 on a maintenant les imports absolus et relatifs via un import du futur :

from __future__ import absolute_import

Je n'ai pas encore eu l'occasion de tester ça moi-même, on va donc couper court à toute discussion à ce sujet.

Actions sur le document