Pendant toute la durée de l’évaluation d’un script, Python peut ouvrir, utiliser et refermer des espaces de nom. Il s’agit d’éviter des conflits d’homonymie (deux identificateurs de même nom, mais de contenus différents, et auxquels on veut continuer à accéder sans que l’un “masque” l’autre).
Au niveau interactif, on est dans l’espace “global”. Son contenu peut d’ailleurs être visualisé avec la fonction globals (qui ne prend pas d’arguments). Voici par exemple le contenu de l’espace de noms global quand on vient juste de lancer l’interpréteur (l’objet affiché est de type dictionnaire) :
|
1 2 3 4 5 |
>>> ================================ RESTART ================================ >>> globals() # on vient de relancer l'interpréteur Python, et on demande les noms globaux {'__package__': None, '__name__': '__main__', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__builtins__': <module 'builtins'>, '__doc__': None} |
Juste après, on crée trois variables globales x, y, z, et on appelle à nouveau la fonction globals. On voit que les noms x, y, z et les contenus correspondants ont été ajoutés au dictionnaire :
|
1 2 3 4 5 |
>>> x, y, z = 1, 2, 3 # on crée les variables globales x, y, z >>> globals() # elles apparaissent maintenant dans l'espace de nom global {'__package__': None, 'y': 2, 'x': 1, '__name__': '__main__', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__builtins__': <module 'builtins'>, 'z': 3, '__doc__': None} |
Continuons, en important cette fois le module math (avec l’instruction import math). En appelant à nouveau la fonction globals, on voit que le module math a été ajouté, mais qu’il ne représente qu’une seule entrée du dictionnaire (pour des raisons de présentation, on a un peu raccourci le chemin d’accès au module) :
|
1 2 3 4 5 6 |
>>> import math >>> globals() {'__package__': None, 'y': 2, 'x': 1, '__name__': '__main__', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__builtins__': <module 'builtins'>, 'z': 3, 'math': <module 'math' from '/Library/.../python3.3/lib-dynload/math.so'>, '__doc__': None} |
Dans la méthode précédente de chargement du module math, les noms des fonctions qui composent ce module ne sont pas directement présents dans l’espace global. Ces noms sont en effet présents dans l’espace de nom du module math, et on peut y accéder à l’aide du préfixe “math.” (par exemple, on écrira math.sqrt(5)).
En revanche, on peut décider de charger le module math avec l’instruction from math import *.
Un nouvel appel à la fonction globals montre qu’alors tous les noms de ce module appartiennent à l’espace global (et le dictionnaire est beaucoup plus volumineux : on a ici considérablement raccourci l’affichage).
|
1 2 3 4 5 6 7 8 |
>>> from math import * >>> globals() {'isinf': <built-in function isinf>, 'tanh': <built-in function tanh>, 'expm1': <built-in function expm1>, 'isnan': <built-in function isnan>, 'log1p': <built-in function log1p>, 'copysign': <built-in function copysign>, <...> 'e': 2.718281828459045, 'log2': <built-in function log2>, 'hypot': <built-in function hypot>, 'asin': <built-in function asin>} |
Avec cette nouvelle méthode, les fonctions du module math sont donc directement accessibles par leur nom court (par exemple sqrt plutôt que math.sqrt). C’est peut-être ce qu’on recherche, mais on s’expose à des problèmes d’homonymie : si deux fonctions portent le même nom, la dernière à avoir été chargée en mémoire occulte la précédente.