Dans de nombreuses ressources, j'ai trouvé que «portée» et «espaces de noms» sont utilisés de manière interchangeable, ce qui semble un peu déroutant car ils signifient des choses différentes.
- La portée définit la région du code où un nom est disponible.
- La règle LEGB définit la façon dont les noms sont recherchés.
- L'espace de noms est un endroit où vous recherchez des noms.
Alors j'ai lu:
- "les noms sont liés à un espace de noms en fonction de l'endroit où ils sont attribués ..." (ce qui, je crois, concerne les portées dans la portée lexicale).
- "les fonctions ajoutent une couche d'espace de noms supplémentaire à vos programmes" [ réf. ] (n'ajoutent-ils pas une portée locale supplémentaire?)
- "tous les noms attribués à l'intérieur d'une définition de fonction sont placés dans la portée locale (l'espace de nom associé à l'appel de fonction)."
- "portée globale - c'est-à-dire un espace de noms dans lequel vivent des variables créées (attribuées) au niveau supérieur du fichier de module."
* toutes les citations proviennent de l'apprentissage de python 5e édition ch17
Les espaces de noms en Python sont-ils la manière dont les étendues sont implémentées? S'agit-il de la même chose? Quelqu'un peut-il m'éclairer?
Réponses:
Un espace de noms est un dictionnaire, mappant des noms (sous forme de chaînes) à des valeurs. Lorsque vous effectuez une affectation, par exemple
a = 1
, vous mutez un espace de noms. Lorsque vous faites une référence, par exempleprint(a)
, Python parcourt une liste d'espaces de noms pour essayer d'en trouver un avec le nom comme clé.Une portée définit quels espaces de noms seront examinés et dans quel ordre. La portée de toute référence commence toujours dans l'espace de noms local et se déplace vers l'extérieur jusqu'à ce qu'elle atteigne l'espace de noms global du module, avant de passer à
builtins
(l'espace de noms qui fait référence aux fonctions et constantes prédéfinies de Python, commerange
etgetattr
), qui est la fin de la ligne .Imaginez que vous ayez une fonction nommée
inner
, imbriquée dans une fonction globale nomméeouter
etinner
contenant une référence à un nom. Python regarde d'abord dans l'inner
espace de noms. Si le nom n'est pas là, Python regarde alors dans l'outer
espace de noms. Si cela échoue, Python essaie l'global
espace de noms du module , puis l'builtin
espace de noms, en lançant éventuellement unNameError
si le nom n'est pas trouvé.Lorsque nous disons qu'il se
x
trouve dans l'espace de noms d'une fonction, nous voulons dire qu'il y est défini localement dans la fonction. Lorsque nous disons qu'ilx
est dans la portée de la fonction, nous voulons dire quex
c'est soit dans l'espace de noms de la fonction, soit dans l'un des espaces de noms externes dans lequel l'espace de noms de la fonction est imbriqué.Chaque fois que vous définissez une fonction, vous créez un nouvel espace de noms et une nouvelle étendue. L'espace de noms est le nouveau hachage local des noms. La portée est la chaîne implicite d'espaces de noms qui commence au nouvel espace de noms, puis se fraye un chemin à travers tous les espaces de noms externes (étendues externes), jusqu'à l'espace de noms global (la portée globale) et jusqu'aux éléments intégrés.
Les termes peuvent être utilisés presque de façon interchangeable, mais ce n'est pas parce qu'ils signifient la même chose; c'est parce qu'ils se chevauchent beaucoup dans ce qu'ils impliquent.
la source
Il y a un excellent article sur les espaces de noms Python ici . Pour citer la partie pertinente pour répondre à votre question sur la référence entre les étendues et les espaces de noms:
Par exemple, imaginez un simple programme de lancer de matrice:
roll
a son propre espace de noms , mais les noms dans l'espace de noms du module sont également dans la portée .la source