Complément - niveau intermédiaire¶
Un exemple¶
python fournit un accès à la liste des noms et valeurs des variables visibles à cet endroit du code. Dans le jargon des langages de programmation on appelle ceci l’environnement.
Cela est fait grâce aux fonctions built-in globals et locals, que nous allons commencer par essayer sur quelques exemples. Nous avons pour cela écrit un module dédié :
import env_locals_globalsdont voici le code
from modtools import show_module
show_module(env_locals_globals)Fichier /__w/course/course/modules/env_locals_globals.py
----------------------------------------
01|"""
02|un module pour illustrer les fonctions globals et locals
03|"""
04|
05|globale = "variable globale au module"
06|
07|def display_env(env):
08| """
09| affiche un environnement
10| on affiche juste le nom et le type de chaque variable
11| """
12| for variable, valeur in sorted(env.items()):
13| print(f"{variable:>20} → {type(valeur).__name__}")
14|
15|def temoin(x):
16| "la fonction témoin"
17| y = x ** 2
18| print(20 * '-', 'globals:')
19| display_env(globals())
20| print(20 * '-', 'locals:')
21| display_env(locals())
22|
23|class Foo:
24| "une classe vide"
et voici ce qu’on obtient lorsqu’on appelle
env_locals_globals.temoin(10)-------------------- globals:
Foo → type
__builtins__ → dict
__cached__ → str
__doc__ → str
__file__ → str
__loader__ → SourceFileLoader
__name__ → str
__package__ → str
__spec__ → ModuleSpec
display_env → function
globale → str
temoin → function
-------------------- locals:
x → int
y → int
Interprétation¶
Que nous montre cet exemple ?
D’une part la fonction
globalsnous donne la liste des symboles définis au niveau de l’espace de noms du module. Il s’agit évidemment du module dans lequel est définie la fonction, pas celui dans lequel elle est appelée. Vous remarquerez que ceci englobe tous les symboles du moduleenv_locals_globals, et non pas seulement ceux définis avanttemoin, c’est-à-dire la variableglobale, les deux fonctionsdisplay_envettemoin, et la classeFoo.D’autre part
localsnous donne les variables locales qui sont accessibles à cet endroit du code, comme le montre ce second exemple qui se concentre surlocalsà différents points d’une même fonction.
import env_locals# le code de ce module
show_module(env_locals)Fichier /__w/course/course/modules/env_locals.py
----------------------------------------
01|"""
02|un module pour illustrer la fonction locals
03|"""
04|
05|# pour afficher
06|from env_locals_globals import display_env
07|
08|def temoin(x):
09| "la fonction témoin"
10| y = x ** 2
11| print(20*'-', 'locals - entrée:')
12| display_env(locals())
13|
14| for i in (1,):
15| for j in (1,):
16| print(20*'-', 'locals - boucles for:')
17| display_env(locals())
env_locals.temoin(10)-------------------- locals - entrée:
x → int
y → int
-------------------- locals - boucles for:
i → int
j → int
x → int
y → int
Complément - niveau avancé¶
NOTE: cette section est en pratique devenue obsolète maintenant que les f-strings sont présents dans la version 3.6.
Nous l’avons conservée pour l’instant toutefois, pour ceux d’entre vous qui ne peuvent pas encore utiliser les f-strings en production. N’hésitez pas à y passer si vous n’êtes pas dans ce cas.
Usage pour le formatage de chaînes¶
Les deux fonctions locals et globals ne sont pas d’une utilisation très fréquente. Elles peuvent cependant être utiles dans le contexte du formatage de chaînes, comme on peut le voir dans les deux exemples ci-dessous.
Avec format¶
On peut utiliser format qui s’attend à quelque chose comme :
"{nom}".format(nom="Dupont")'Dupont'que l’on peut obtenir de manière équivalente, en anticipant sur la prochaine vidéo, avec le passage d’arguments en ** :
"{nom}".format(**{'nom': 'Dupont'})'Dupont'En versant la fonction locals dans cette formule on obtient une forme relativement élégante
def format_et_locals(nom, prenom, civilite, telephone):
return "{civilite} {prenom} {nom} : Poste {telephone}".format(**locals())
format_et_locals('Dupont', 'Jean', 'Mr', '7748')'Mr Jean Dupont : Poste 7748'Avec l’opérateur %¶
De manière similaire, avec l’opérateur % - dont nous rappelons qu’il est obsolète - on peut écrire
def pourcent_et_locals(nom, prenom, civilite, telephone):
return "%(civilite)s %(prenom)s %(nom)s : Poste %(telephone)s"%locals()
pourcent_et_locals('Dupont', 'Jean', 'Mr', '7748')'Mr Jean Dupont : Poste 7748'Avec un f-string¶
Pour rappel si vous disposez de python 3.6, vous pouvez alors écrire simplement - et sans avoir recours, donc, à locals() ou autre :
# attention ceci nécessite python-3.6
def avec_f_string(nom, prenom, civilite, telephone):
return f"{civilite} {prenom} {nom} : Poste {telephone}"
avec_f_string('Dupont', 'Jean', 'Mr', '7748')'Mr Jean Dupont : Poste 7748'