Espace de nommage
Nous avons déjà abordé la notion d' lorsque :
- on a paré de modules : l'espace de nommage du module et accès aux éléments via la notation pointée
- on a parlé des fonctions : l'espace de nommage et fonctions
Les espaces de nommage permettent de lier variables et objets :
- on considère que les objets sont stockés dans l'espace des objets : cet espace est unique
- on accède aux objets via leurs noms, eux même stockés dans des espaces de nommage qui sont des objets comme les autres : il y en a de nombreux.
Pour chaque espace de nommage :
- il ne peut y avoir 2 noms identiques
- à chaque nom est associé un objet
- certains espaces de noms possèdent un parent qui sera utilisé si on ne trouve pas un nom.
De façon formelle :
Définition
Un espace de nommage est table de correspondance (un dictionnaire) associant des noms (les clés) à des objets (les valeurs). Il contient également un lien vers son parent qui est soit :
- vide
- un autre espace de nommage
- l'espace des variables
Par exemple les espaces de nommages associés aux modules on par exemple un parent vide et ceux créés par les fonctions dépendant de l'espace de nommage qui les a appelé.
À retenir
Les espaces de nommages sont utilisés à de nombreux endroits dans python et sont là pour :
- gérer les noms et leurs objets associés
- séparer les responsabilités et cloisonner les noms auxquels ont accès les différentes parties d'un programme
Avant de détailler ce mécanisme, commençons par rappeler ce qu'est un nom et un objet pour python.
Rappel sur les variables et les objets
Commençons par quelques rappels et précisions sur les variables et leurs liens avec les objets :
- tout ce que manipule un programme est appelé objet.
- les variables sont des noms via lesquels on accède aux objets. On dit aussi parfois qu'une variable est une référence à un objet.
À retenir
Pour qu'un programme objet fonctionne, on a besoin de deux mécanismes :
- un moyen de stocker des données et de les manipuler (les objets et leurs méthodes)
- un moyen d'y accéder (les variables)
Objets
Un objet est une structure de donnée générique permettant de gérer tout ce dont à besoin un programme :
- des données
- des fonctions
- des modules
- ...
À retenir
Tout est objet dans un langage objet.
Variables
Les variables sont des références aux objets. Pour ce faire, on utilise l’opérateur d’affectation = :
variable = objet
A gauche de l’opérateur = se trouve une variable (en gros, quelque chose ne pouvant commencer par un nombre) et à droite un objet. Dans toute la suite du programme, dès que le programme rencontrera le nom, il le remplacera par l'objet.
À retenir
Une variable n'est pas l'objet, c'est une référence à celui-ci
La variable peut être vue comme un nom de l'objet à ce moment du programme. Un objet pourra avoir plein de noms différents au cours de l'exécution du programme, voire plusieurs noms en même temps.
Pour s'y retrouver et avoir une procédure déterministe pour retrouver les objets associés aux variables, voire choisir parmi plusieurs variables de même nom, elles sont regroupées par ensembles — nommés espaces de noms — hiérarchiquement ordonnés.
Espaces des variables
L'espace des variables peut-être vu comme un espace de nom particulier : c'est celui qui est créé au début de l'exécution de l'interpréteur.
À retenir
Au démarrage d'une exécution d'un programme, l'espace des variables est créé. C'est à partir de lui que toutes les variables doivent être atteintes.
Au départ, cet espace il ne contient rien, à part des variables spéciales (qui ont des noms commençant et finissant par __) utilisées par python. On en verra certaines pendant ce cours, mais ce qu'il faut retenir c'est que ces variables permettent à python de fonctionner. Elles sont mises à disposition des développeurs mais on ne les utilisera jamais dans un usage courant.
Pour voir les noms définis dans l'espace de noms des variables, on utilise en python la fonction globals() qui rend le dictionnaire dont les clés sont les noms des variables et les valeurs les objets associés.
>>> type(globals())
<class 'dict'>
>>> globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__builtins__'])
On voit que des variables existent dès le démarrage de python. Ces variables ne sont pas là pour être utilisées par nous mais sont indispensables au bon fonctionnement de python :
__name__,__doc__,__packages__.__loader__et__spec__existent pour tout espace de nommage et permettent leur bon fonctionnement__builtins__est un module et contient toutes les fonctions de python (il contient les nomsprint,input, etc)
Certains langages vont cacher leur fonctionnement interne à l'utilisateur. Ce n'est pas le cas de python qui veut que tout soit explicite : on a accès via ces variables spéciales au fonctionnement interne de python que l'on peut examiner, voir modifier (mais ne le faites pas...)
Ajoutons une variable et vérifions qu'elle est ajoutée à l'espace des variables :
>>> x = "youhou ! Je suis là !"
>>> globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__builtins__', 'x'])
Notre variable a bien été ajouté à l'espace des noms. Comme c'est un dictionnaire, on peut y accéder directement :
>>> globals()['x']
'youhou ! Je suis là !'
Qui est équivalent à :
>>> print(x)
'youhou ! Je suis là !'
Voir même y ajouter directement des variables. La ligne suivante est équivalente à affecter une nouvelle variable y :
>>> globals()['y'] = "je suis un véritable hacker."
Vérifions le :
>>> print(y)
je suis un véritable hacker.
À retenir
L'espace de variable est l'espace de nommage principal. On doit pouvoir accéder à tous les objets via celui-ci.
Espaces de nommage des modules
On a vu qu'un module contenait un espace de nommage auquel on pouvait accéder via la notation pointée.
Tout comme la fonction globals() permet d'accéder au dictionnaire contenant la table de relation entre variables et objets, il est possible d'accéder au dictionnaire contenant les noms stockés dans l'espace de nommage d'un objet o (en particulier d'un module) en utilisant la fonction vars(o).
Testons cela :
Dans un projet vscode créez deux fichiers :
- un fichier
main.pycontenant le code :import mon_module print(vars(mon_module).keys()) - un fichier
mon_module.pyvide
Pius exécutez le fichier avec la commande python main.py.
Lorsque vous exécutez le fichier main.py vous devriez voir :
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__'])
On retrouve les variables spéciales de l'espace de variables (__name__,__doc__, __packages__. __loader__, __spec__ et __builtins__) plus deux nouvelles variables :
__file____file__
TBD créer un fichier vide et on l'importe. TBD vars permet de connaître l'espace de nom d'un objet qui en possède un. TBD on retrouve les éléments d'avant. TDB voir le main
TBD comme globals, un espace de nom est mutable : on utilise = et la notation pointé tout comme on ferait un = pour les variables.
Espaces local et hiérarchie des espaces de nommages
TBD locals TBD fonctions. TBD trouver une variable au delà de son espace mais affectation dans l'espace locale
TBD fonctions récursives