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.
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.
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.
|