Python >> Tutoriel Python >  >> Python

Règles de portée Python - Un guide illustré simple

Introduction à la portée en Python

❖ Qu'est-ce que le nom en Python ?

Tout en Python est un objet. Puisque tout est un objet, nous devons identifier et distinguer chaque type d'objet les uns des autres et c'est ce que fait un nom. Le nom est simplement un nom unique donné aux objets en Python afin qu'ils puissent être identifiés. Par exemple, lorsqu'une fonction est définie dans un programme, on lui donne un nom qui est utilisé pour identifier la fonction. Un autre exemple est une simple affectation de variable var = 25 . Ici 2 est l'objet stocké en mémoire tandis que var est le nom donné à l'objet.

❖ Qu'est-ce que la portée ?

La portée d'un nom comme une variable, une fonction, un objet, etc. est la région ou la partie du programme où le nom peut être accédé directement. En d'autres termes, un nom n'est visible et accessible que dans sa portée.

❖ Qu'est-ce qu'un espace de noms ?

Un espace de noms est simplement une collection de noms. C'est un conteneur qui contient les noms mappés à leurs objets respectifs. Les espaces de noms sont isolés ; ainsi, les mêmes noms dans des portées différentes n'entrent pas en collision.

? L'espace de noms qui contient tous les noms intégrés est créé par défaut à cause de quelles fonctions intégrées comme print() est accessible à partir de toutes les parties du programme.

❖ Exemple

name = "FINXTER"
print("Name in Global Scope: ", name)
def foo():
    name = "PYTHON"
    print("Name in Local Scope: ", name)
foo()

Sortie :

Name in Global Scope:  FINXTER
Name in Local Scope:  PYTHON

Dans l'exemple ci-dessus, nous pouvons voir que la variable se trouve dans l'espace de noms global ainsi qu'à l'intérieur de l'espace de noms local et n'entre pas en collision. Cela nous amène maintenant à une discussion très importante sur les portées variables et le LEGB règle de résolution de la portée.

Le LEGB Champs d'application des règles et des variables

LEGB est une abréviation pour Local(L)-Enclosed(E)-Global(G)-Built-In(B) et il est utilisé pour définir la résolution de Python Scope. Comprenons ce qu'est la résolution de portée et comment fonctionne LEGB.

Avis de non-responsabilité : Les règles LEGB sont spécifiques aux noms de variables et non aux attributs.

❖ Portée locale (L)

Lorsqu'une variable/un nom est créé à l'intérieur d'une fonction, il n'est disponible que dans le cadre de cette fonction et cesse d'exister s'il est utilisé en dehors de la fonction. Ainsi la variable appartient à la portée locale de la fonction. Chaque fois que la fonction est appelée, une nouvelle portée locale est créée. La portée locale est également appelée portée de la fonction .

Exemple :

def foo():
  scope = "local variable"
  print(scope)
foo()

Sortie :

local variable

❖ Champ d'application (E)

Une portée englobante se produit lorsque nous avons des fonctions imbriquées. Lorsque la variable est dans la portée de la fonction extérieure, cela signifie que la variable est dans la portée englobante de la fonction. Par conséquent, la variable est visible dans le cadre des fonctions internes et externes. La portée englobante est souvent appelée non locale portée.

def foo():
  scope = "enclosed variable"
  def func():
    print(scope)
  func()
foo()

Sortie :

variable fermée

Dans l'exemple ci-dessus, la variable scope est à l'intérieur de la portée englobante de la fonction foo() et disponible à l'intérieur du foo()  ainsi que func() fonctions.

❖ Portée mondiale (G)

Une variable globale est une variable qui est déclarée dans une portée globale et peut être utilisé dans l'ensemble du programme ; cela signifie qu'il est accessible à l'intérieur comme à l'extérieur de la portée d'une fonction. Un nom global est généralement déclaré en dehors des fonctions, dans le corps principal du code Python. Dans le backend, Python convertit le script principal du programme en __main__ module responsable de l'exécution du programme principal. L'espace de noms du __main__ module est la portée globale.

Exemple :

name = "FINXTER"
def foo():
    print("Name inside foo() is ", name)
foo()
print("Name outside foo() is :", name)

Sortie :

Name inside foo() is FINXTER
Name outside foo() is : FINXTER

❖ Portée intégrée (B)

La portée intégrée est la portée la plus large disponible en python et contient des mots clés, des fonctions, des exceptions et d'autres attributs intégrés à Python. Les noms dans la portée intégrée sont disponibles dans tout le programme python. Il est chargé automatiquement au moment de l'exécution d'un programme/script Python.

Exemple

x = 25
print(id(x))

Sortie :

140170668681696

❖ Exemple de règles de portée en Python

x = 100
print("1. Global x:", x)
class Test(object):
    y = x
    print("2. Enclosed y:", y)
    x = x + 1
    print("3. Enclosed x:", x)

    def method(self):
        print("4. Enclosed self.x", self.x)
        print("5. Global x", x)
        try:
            print(y)
        except NameError as e:
            print("6.", e)

    def method_local_ref(self):
        try:
            print(x)
        except UnboundLocalError as e:
            print("7.", e)
        x = 200 # causing 7 because has same name
        print("8. Local x", x)

inst = Test()
inst.method()
inst.method_local_ref()

Sortie :

1. Global x: 100
2. Enclosed y: 100
3. Enclosed x: 101
4. Enclosed self.x 101
5. Global x 100
6. name 'y' is not defined
7. local variable 'x' referenced before assignment
8. Local x 200

Le schéma suivant fournit une représentation graphique des règles de portées en Python :

Comprendre UnboundLocalError En Python

Lorsqu'une variable est assignée dans une fonction, elle est traitée comme une variable locale par défaut dans Python. Si une variable locale est référencée avant qu'une valeur lui ait été assignée/liée, un UnboundLocalError  est relevé. Dans l'exemple ci-dessus lorsque la variable 'val' est lu par l'interpréteur Python à l'intérieur du func() fonction, il suppose que 'val' est une variable locale. Cependant, il se rend vite compte que la variable locale a été référencée avant qu'une valeur ne lui ait été affectée dans la fonction. Ainsi, il lance un UnboundLocalError .

En d'autres termes, nous ne pouvons accéder qu'à une variable globale à l'intérieur d'une fonction mais ne pouvons pas la modifier depuis l'intérieur de la fonction (sauf si vous forcez une affectation globale ou non locale à l'aide du global  ou nonlocal mots-clés).

Exemple :

val = 100
def func():
    val = val + 100
    print(val)
func()

Sortie :

Traceback (most recent call last):
  File "C:/Users/Shubham-PC/PycharmProjects/pythonProject1/main.py", line 9, in <module>
    func()
  File "C:/Users/Shubham-PC/PycharmProjects/pythonProject1/main.py", line 5, in func
    val = val + 100
UnboundLocalError: local variable 'val' referenced before assignment

Résolution : Pour résoudre un UnboundLocalError  lorsque la variable locale est réaffectée après la première utilisation, vous pouvez soit utiliser le global mot-clé ou le nonlocal mot-clé. Le global Le mot clé vous permet de modifier les valeurs d'une variable globale à partir de la portée locale d'une fonction tandis que le nonlocal Le mot-clé fournit des fonctionnalités similaires dans le cas des fonctions imbriquées.

Cela nous amène à un sujet très important - global et nonlocal mots-clés.

Le mondial Et non local Mot clé en Python

❖ Le mot-clé global

Nous avons déjà lu sur la portée globale où nous avons appris que chaque variable déclarée dans le corps principal et en dehors de toute fonction dans le code Python est globale par défaut. Cependant, si nous avons une situation où nous devons déclarer une variable globale à l'intérieur d'une fonction comme dans l'énoncé du problème de cet article, alors le mot-clé global vient à notre secours. Nous utilisons le global keyword à l'intérieur d'une fonction pour rendre une variable globale dans la portée locale. Cela signifie que le mot clé global nous permet de modifier et d'utiliser une variable en dehors de la portée de la fonction dans laquelle elle a été définie.

Examinons maintenant le programme suivant pour comprendre l'utilisation du global  mot-clé.

def foo():
    global name
    name = "PYTHON!"
    print("Name inside foo() is ", name)
foo()
name = "FINXTER "+name
print("Name outside foo() is ", name)

Sortie :

Name inside foo() is  PYTHON!
Name outside foo() is  FINXTER PYTHON!

❖ Le mot clé non local

Le nonlocal  Le mot clé est utile lorsque nous avons une fonction imbriquée, c'est-à-dire des fonctions ayant des variables dans la portée englobante. En d'autres termes, si vous souhaitez changer/modifier une variable qui se trouve dans la portée de la fonction englobante (fonction externe), vous pouvez utiliser le nonlocal  mot-clé. Si nous changeons la valeur d'un nonlocal variable la valeur du local la variable change également.

Exemple :

def foo():
  a = 25
  print("Value of 'a' before calling func = ",a)
  def func():
    nonlocal a
    a=a+20
    print("Value of 'a' inside func = ",a)
  func()
  print("Value of 'a' after exiting func = ",a)
foo()

Sortie :

Value of 'a' before calling func =  25
Value of 'a' inside func =  45
Value of 'a' after exiting func =  45

❖ Mot clé global vs mot clé non local

Avant de conclure cet article, examinons les principales différences entre un global et nonlocal variables/mots clés.

  1. Contrairement au global mot-clé, le nonlocal mot-clé ne fonctionne qu'en Python 3 et supérieur.
  2. Le global le mot-clé peut être utilisé avec des variables globales préexistantes ou de nouvelles variables alors que le nonlocal le mot-clé doit être défini avec une variable préexistante.

Conclusion

Dans cet article, nous avons appris ce qui suit :

  • Que sont les noms en Python ?
  • Que sont les espaces de noms en Python ?
  • Que sont les champs d'application en Python ?
  • La règle de résolution de portée LEGB en Python.
  • L'erreur locale non liée.
  • Le mot clé global et non local.

Veuillez vous abonner et rester à l'écoute pour plus d'articles !