Sous-sections


6. Modules

Si vous quittez l'interprèteur de Python et le lancez à nouveau, les définitions que vous avez faites (fonctions et variables) sont perdues. Par conséquent, si vous voulez écrire un programme plus long, vous feriez mieux d'utiliser à la place un éditeur de texte pour préparer le source pour l'interpréteur et de le lancer avec ce fichier comme entrée. Ceci s'appelle créer un script. Quant votre programme devient plus long, vous pouvez vouloir le couper en plusieurs fichiers pour une maintenance plus facile. Vous pouvez également vouloir utiliser dans plusieurs programmes une fonction pratique que vous avez écrite sans copier sa définition dans chaque programme.

Pour supporter ceci, Python offre un moyen de mettre des définitions dans un fichier et de les utiliser dans un script ou dans un session interactive de l'interpréteur. Un tel fichier s'appelle un module; les définitions d'un module peuvent être importées dans un autre module ou dans le module principal (la collection de variables à laquelle vous avez accès dans un script exécuté depuis le plus haut niveau et dans le mode calculatrice).

Un module est un fichier contenant des définitions et des instructions Python. Le nom de fichier est le nom du module auquel est ajouté le suffixe .py. Dans un module, le nom du module (comme chaîne de caractères) est disponible comme valeur de la variable globale __name__. Par exemple, employez votre éditeur de texte préféré pour créer un fichier appelé fibo.py dans le répertoire courant avec le contenu suivant:

# Module nombres de Fibonacci 

def fib(n):    # écrit la série de Fibonacci jusqu'à n
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b

def fib2(n): # retourne la série de Fibonacci jusqu'à n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

Maintenant lancez l'interpréteur Python et importez ce module avec la commande suivante:

>>> import fibo

Ceci n'écrit pas les noms des fonctions définies dans fibo directement dans la table de symboles actuelle; cela y insère seulement le nom de module fibo. En utilisant le nom de module vous pouvez accéder aux fonctions:

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

si vous avez l'intention d'utiliser souvent une fonction, vous pouvez l'affecter à un nom local:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377


6.1 Encore Plus sur les Modules

Un module peut contenir des instructions exécutables aussi bien que des définitions de fonction. Ces instructions sont destinées à initialiser le module. On les exécute seulement la première fois que le module est importé quelque part.6.1

Chaque module a sa propre table de symboles privée, qui est utilisée comme table de symbole globale par toutes les fonctions définies dans le module. Ainsi, l'auteur d'un module peut utiliser des variables globales dans le module sans s'inquiéter des désaccords accidentels avec les variables globales d'un utilisateur. D'autre part, si vous savez que ce que vous faites, vous pouvez accéder aux variables globales d'un module avec la même notation que celle employée pour se référer à ses fonctions, nommodule.nomelem.

Les modules peuvent importer d'autres modules. Il est d'usage mais pas obligatoire de placer toutes les instructions import au début d'un module (ou d'un script). Les noms du module importé sont placés dans la table globale de symboles du module importateur.

Il y a une variante de l'instruction import qui importe des noms d'un module directement dans la table de symboles du module importateur. Par exemple:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Ceci n'introduit pas dans la table de symboles locale le nom du module duquel les éléments importés sont issus (ainsi dans l'exemple, fibo n'est pas défini).

Il y a même une variante pour importer tous les noms qu'un module définit:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Ceci importe tous les noms excepté ceux qui commencent par un tiret-bas (_).


6.1.1 Le Chemin de Recherche du Module

Quand un module nommé spam est importé, l'interpréteur recherche un fichier nommé spam.py dans le répertoire courant, et puis dans la liste de répertoires indiquée par la variable d'environnement $PYTHONPATH. Elle a la même syntaxe que la variable du shell $PATH, c.-à-d., une liste de noms de répertoire. Quand $PYTHONPATH n'est pas renseigné, ou quand le fichier n'y est pas trouvé, la recherche continue dans un chemin d'accès par défaut, dépendant de l'installation ; sur Unix, c'est habituellement .:/usr/local/lib/python.

En fait, les modules sont recherchés dans la liste de répertoires donnée par la variable sys.path qui est initialisée à partir du répertoire contenant le script d'entrée (ou le répertoire actuel), $PYTHONPATH et le chemin par défaut, dépendant de l'installation. Ceci permet aux programmes Python qui savent ce qu'ils font de modifier ou de remplacer le chemin d'accès aux modules. Voyez la section sur les modules standards plus tard.

6.1.2 Fichiers ``Compilés'' de Python

Pour accélérer de manière importante le temps de lancement des petits programmes qui utilisent beaucoups de modules standard, si un fichier appelé spam.pyc existe dans le répertoire où spam.py se trouve, il est supposé contenir une version du module spam déjà compilée ``en byte-code'' L'heure de modification de la version de spam.py employée pour créer spam.pyc est enregistrée dans spam.pyc, et le fichier est ignoré si ceux-ci ne s'accordent pas.

Normalement, vous n'avez rien à faire pour créer le fichier spam.pyc. Toutes les fois que spam.py est compilé avec succès, une tentative est faite pour écrire la version compilée sur spam.pyc. Il n'y a pas d'erreur si cette tentative échoue; si pour une raison quelconque le fichier n'est pas écrit complètement, le fichier spam.pyc résultant sera identifié comme incorrect et ainsi ignoré plus tard. Le contenu du fichier spam.pyc est indépendant de la plate-forme, ainsi un répertoire de module de Python peut être partagé par des machines d'architectures différentes.

Quelques trucs pour les experts:

  • Quand l'interpréteur de Python est appelé avec l'indicateur -O, du code optimisé est produit et enregistré dans des fichiers .pyo. L'optimiseur actuel n'aide pas beaucoup; il retire seulement les instructions assert et des instructions SET_LINENO. Quand -O est utilisé, tout le byte-code est optimisé; les fichiers pyc sont ignorés et des fichiers py sont compilés en byte-code optimisé.

  • Passer deux options -O en paramètres à l'interpréteur Python (-OO) forcera le compilateur de bytecode à effectuer des optimisations qui pouraient dans certains cas rares avoir pour résultat des programmes ne foctionnant pas correctement. Actuellement, seules les chaînes __doc__ sont enlevées du bytecode, ce qui a pour résultat des fichiers .pyo plus compacts. Puisque certains programmes pourraient s'appuyer sur le fait que celles-ci soient disponibles, vous devriez utiliser cette option uniquement si vous savez ce que vous faites.

  • Un programme ne fonctionne pas plus rapidement quand on le charge depuis un fichier `.pyc' ou .pyo que quand on le charge depuis un .py; la seule chose qui est plus rapide pour les fichiers .pyc ou .pyo est la vitesse à laquelle ils sont chargés.

  • Quand un script est exécuté en donnant son nom sur la ligne de commande, le byte-code pour le script n'est jamais écrit dans un fichier .pyc ou .pyo. Ainsi, le temps de démarrage d'une séquence type peut être réduit en déplaçant la majeure partie de son code dans un module et en ayant un petit script d'amorce qui importe ce module.

  • Il est possible d' avoir un fichier appelé spam.pyc (ou spam.pyo quand -O est utilisé) sans module spam.py dans le même module. Ceci peut être employé pour distribuer une bibliothèque de code Python sous une forme qui est moyennement difficile à décompiler.

  • Le module compileall peut créer des fichiers .pyc (ou des fichiers .pyo quand -O est utilisé) pour tous les modules présents dans un répertoire.


6.2 Modules Standard

Python est livré avec une bibliothèque de modules standard, décrite dans un document séparé, Python Library Reference (``Library Reference'' ci-après). Quelques modules sont intégrés dans l'interpréteur; ceux-ci permettent d'accéder à des opérations qui ne font pas partie du noyau du langage mais sont néanmoins intégrées, pour des raisons d'efficacité ou pour permettre d'accéder aux primitives du système d'exploitation telles que les appels système. La définition de l'ensemble de ces modules standards est une option de configuration; par exemple, le module amoeba est seulement fourni sur les systèmes qui supportent d'une façon ou d'une autre les primitives d'Amoeba. Un module particulier mérite une certaine attention: sys, qui est intégré dans chaque interpréteur de Python. Les variables sys.ps1 et sys.ps2 définissent les chaînes de caractères utilisées en tant qu'invites primaire et secondaire:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>

Ces deux variables sont seulement définies si l'interpréteur est en mode interactif.

La variable sys.path est une liste de chaînes de caractères qui déterminent le chemin de recherche des modules pour l'interpréteur. Il est initialisé à un chemin par défaut à partir de la variable d'environnement $PYTHONPATH, ou d'une valeur par défaut intégrée au programme si $PYTHONPATH n'est pas renseigné. Vous pouvez la modifier en utilisant des opérations standard sur des listes, par exemple:

>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')


6.3 La Fonction dir()

La fonction intégrée dir() est employée pour découvrir les noms qu'un module définit. Elle renvoie une liste triée de chaînes de caractères:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__name__', 'argv', 'builtin_module_names', 'copyright', 'exit',
'maxint', 'modules', 'path', 'ps1', 'ps2', 'setprofile', 'settrace',
'stderr', 'stdin', 'stdout', 'version']

Sans arguments, dir() énumère les noms que vous avez définis:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo, sys
>>> fib = fibo.fib
>>> dir()
['__name__', 'a', 'fib', 'fibo', 'sys']

Notez qu'elle énumère tous les types de noms: les variables, les modules, les fonctions, etc.

dir() n'énumère pas les noms des fonctions et des variables intégrées. Si vous en voulez une liste, elles sont définies dans le module standard __builtin__:

>>> import __builtin__
>>> dir(__builtin__)
['AccessError', 'AttributeError', 'ConflictError', 'EOFError', 'IOError',
'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
'MemoryError', 'NameError', 'None', 'OverflowError', 'RuntimeError',
'SyntaxError', 'SystemError', 'SystemExit', 'TypeError', 'ValueError',
'ZeroDivisionError', '__name__', 'abs', 'apply', 'chr', 'cmp', 'coerce',
'compile', 'dir', 'divmod', 'eval', 'execfile', 'filter', 'float',
'getattr', 'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'len', 'long',
'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'range', 'raw_input',
'reduce', 'reload', 'repr', 'round', 'setattr', 'str', 'type', 'xrange']


6.4 Paquetages

Les paquetages sont un moyen de structurer l'espace des noms de modules Python en utilisant ``les noms de modules pointés''. Par exemple, le nom de module A.B désigne un sous-module nommé "B" dans un module nommé "A". Tout comme l'utilisation des modules permet aux auteurs de différents modules de ne pas s'inquiéter au sujet des noms des variables globales de chacun des autres modules, l'utilisation des noms de modules pointés dispense l'auteur de paquetages multi-modules comme NumPy ou PIL de devoir s'inquiéter au sujet de leurs noms de modules.

Supposez que vous vouliez concevoir une collection de modules (un ``paquetage'') pour la manipulation uniforme des fichiers de sons et des données de son. Il y a beaucoup de formats de fichier de sons différents (habituellement reconnus par leur extension, par exemple .wav, .ai, .au), ainsi vous pouvez avoir besoin de créer et mettre à jour une collection grandissante de module pour la conversion entre les divers formats de fichier. Il y a également beaucoup d'opérations différentes que vous pourriez vouloir exécuter sur des données de sons (par exemple le mixage, ajouter de l'écho, appliquer une fonction d'égalisation, créer un effet artificiel de stéréo), ainsi en complément, vous écrirez une série interminable de modules pour réaliser ces opérations. Voici une structure possible pour votre paquetage (exprimé en termes de système de fichiers hiérarchique):

Sound/                          Paquetage de niveau supérieur
      __init__.py               Initialisation du paquetage sons
      Formats/                  Sous-paquetage pour la conversion des formats de fichiers
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      Effects/                  Sous-paquetage pour les effets sonores
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      Filters/                  Sous-paquetage pour les filtres
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Les fichiers __init__.py sont obligattoires pour que Python considère les répertoires comme contenant des paquetages; ceci est fait pour empêcher des répertoires avec un nom commun, tel que "string", de cacher involontairement les modules valides qui apparaissent plus tard dans le chemin de recherche de module. Dans le cas le plus simple, __init__.py peut juste être un fichier vide, mais doit pouvoir également exécuter du code d'initialisation pour le paquetage ou positionner la variable __all__, décrite ci-dessous.

Les utilisateurs du paquetage peuvent importer individuellement des modules du paquetage, par exemple:

import Sound.Effects.echo

Ceci charge le sous-module Sound.Effects.echo. Il doit être référencé avec son nom complet, par exemple.

Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)

Une autre solution pour importer le sous-module est:

from Sound.Effects import echo

Ceci charge le sous-module echo, et le rend également disponible sans son préfixe de paquetage, ainsi il peut être utilisé comme suit:

echo.echofilter(input, output, delay=0.7, atten=4)

Une autre variante consiste encore à importer la fonction ou la variable désirée directement:

from Sound.Effects.echo import echofilter

Encore une fois, ceci charge le sous-module echo, et rend sa fonction echofilter disponible directement:

echofilter(input, output, delay=0.7, atten=4)

Notez qu'en utilisant from paquetage import element, l'élément peut être un sous-module (ou sous-paquetage) du paquetage, ou un autre nom défini dans le paquetage, comme une fonction, une classe ou une variable. L'instruction import teste d'abord si l'élément est défini dans le paquetage; sinon, elle suppose que c'est un module et essaye de le charger. Si elle ne le trouve pas, ImportError est déclenché.

Au contraire, en utilisant la syntaxe import element.souselement.soussouselement, chaque élément excepté le dernier doit être un paquetage; le dernier élément peut être un module ou un paquetage mais ne peut pas être une classe ou une fonction ou une variable définie dans l'élément précédent.


6.4.1 Importer * Depuis un Paquetage

Maintenant, qu'est-ce qui se produit quand l'utilisateur écrit from Sound.Effects import * ? Dans le meilleur des cas, on espérerait que ceci s'adresse d'une façon ou d'une autre au système de fichiers, trouve quels sous-modules sont présents dans le paquetage, et les importe tous. Malheureusement, cette opération ne fonctionne pas très bien sur des plate-formes Mac et Windows, où le système de fichiers n'a pas toujours des informations précises sur la casse d'un nom de fichier! Sur ces plate-formes, il n'y a aucun moyen garanti de savoir si un fichier ECHO.PY devrait être importé en tant que module echo, Echo ou ECHO. (Par exemple, Windows 95 a la fâcheuse habitude de montrer tous les noms de fichier avec une première lettre en capitale.) La restriction de nom de fichier DOS 8+3 ajoute un autre problème intéressant pour les longs noms de modules.

La seule solution est que l'auteur de module fournisse un index explicite du module. L'instruction d'importation utilise la convention suivante: si le code __init__.py d'un paquetage définit une liste nommée __all__, celle-ci est utilisée comme la liste des noms de modules qui doivent être importés quand from paquetage import * est rencontré. Il appartient à l'auteur du paquetage de tenir cette liste à jour quand une nouvelle version du paquetage est livrée. Les auteurs de paquetage peuvent également décider de ne pas la supporter, s'ils ne souhaitent pas une utilisation d'importation par * de leur module. Par exemple, le fichier Sounds/Effects/__init__.py pourrait contenir le code suivant:

__all__ = ["echo", "surround", "reverse"]

Ceci signifierait que from Sound.Effects import * importerait les trois sous-modules du paquetage Sound

Si __all__ n'est pas défini, l'instruction from Sound.Effects import * n'importe pas dans l'espace des noms actuel l'ensemble des sous-modules du paquetage Sound.Effects; elle s'assure seulement que le paquetage Sound.Effects a été importé (probablement en exécutant son code d'initialisation, __init__.py) et puis importe tous les noms définis dans le module, quels qu'ils soient. Ceci inclut tout nom défini (et tout sous-module chargé explicitement) par __init__.py. Elle inclut également tous les sous-modules du paquetage qui ont été chargés de façon explicite par des instructions d'importation précédentes, par exemple.

import Sound.Effects.echo
import Sound.Effects.surround
from Sound.Effects import *

Dans cet exemple, les modules echo et surround sont importés dans l'espace des noms actuel parce qu'ils sont définis dans le paquetage Sound.Effects quand l'instruction from...import est exécutée. (Ceci fonctionne également quand __all__ est défini.)

Notez qu'en général la pratique de l'importation par * d'un module ou paquetage fait froncer les sourcils, puisqu'elle conduit souvent à un code très peu lisible. Cependant, il est correct de l'employer pour éviter la saisie au clavier lors des sessions interactives, et parce que certains modules sont conçus pour exporter seulement les noms qui correspondent à certains motifs.

Rappelez-vous, il n'y a rien d'incorrect à utiliser from Paquetage import sous_module_specifique ! En fait, c'est la notation recommandée à moins que le module importateur ne doive utiliser des sous-modules avec le même nom, issus de paquetages différents.

6.4.2 Références Intra-Paquetage

Les sous-modules doivent souvent se faire référence mututellement. Par exemple, le module surround pourrait utiliser le module echo. En fait, de telles références sont si communes que l'instruction import regarde d'abord dans le paquetage contenant avant de regarder dans le chemin de recherche standard de module. Ainsi, le module surround peut simplement utiliser import echo ou from echo import echofilter. Si le module importé n'est pas trouvé dans le paquetage actuel (le paquetage dont le module actuel est un sous-module), l'instruction import recherche un module au niveau supérieur avec le nom donné.

Quand des paquetages sont structurés dans des sous-paquetages (comme avec le paquetage Sound dans l'exemple), il n'y a aucun raccourci pour se référer à des sous-modules des paquetages enfants de mêmes parents -- le nom complet du sous-paquetage doit être utilisé. Par exemple, si le module Sound.Filters.vocoder doit utiliser le module echo du paquetage Sound.Effects, il peut utiliser from Sound.Effects import echo.



Notes

... part.6.1
En fait, les définitions de fonctions sont aussi des 'instructions' qui sont 'exécutées'; l'exécution insère le nom de la fonction dans la table de symboles globale du module.

See About this document... for information on suggesting changes.