cours
Portée des variables en Python
Si vous êtes familier avec Python ou tout autre langage de programmation, vous savez sans doute que les variables doivent être définies avant de pouvoir être utilisées dans votre programme. Dans ce tutoriel, vous commencerez par l'initialisation des variables. Ensuite, vous vous familiariserez avec les limites des variables au sein d'un programme - sa "portée". Vous apprendrez à connaître les quatre portées différentes à l'aide d'exemples : locale, englobante, globale et intégrée. Ces scopes forment ensemble la base de la règle LEGB utilisée par l'interprète Python lorsqu'il travaille avec des variables. Ensuite, vous revisiterez quelques exemples avec une complexité supplémentaire pour ouvrir la voie au mot-clé global suivi du mot-clé non local.
Variable
Une variable est une étiquette ou un nom donné à un certain emplacement dans la mémoire. Cet emplacement contient la valeur dont vous voulez que votre programme se souvienne, pour une utilisation ultérieure. Ce qui est génial avec Python, c'est que vous n'avez pas besoin d'indiquer explicitement le type de la variable que vous voulez définir - elle peut être de n'importe quel type (chaîne de caractères, entier, flottant, etc.). Pour créer une nouvelle variable en Python, il vous suffit d'utiliser l'opérateur d'affectation (=
, un simple signe égal) et de lui attribuer la valeur souhaitée.
first_string_var = "First String"
first_int_var = 1
total = 1 + 2 * 3
L'attribution d'une valeur initiale à une variable s'appelle l'initialisation de la variable. Vous venez d'initialiser la variable : first_string_var
avec la valeur de chaîne de caractères First String et la variable first_int_var
avec une valeur entière ou numérique de 1.
La partie à gauche de l'opérateur d'affectation est le nom de la variable, et la partie à droite est sa valeur. Le côté droit peut également être une opération arithmétique - dans ce cas, il sera évalué avant l'affectation.
Python a quelques règles à respecter lors de la création d'une variable...
- Il ne peut contenir que des lettres (majuscules ou minuscules), des chiffres ou le caractère de soulignement
_
. - Il peut ne pas commencer par un chiffre.
- Il peut ne pas s'agir d'un mot-clé (vous en apprendrez plus à ce sujet plus tard).
Si vous ne respectez pas ces règles, vous obtiendrez une erreur. Essayez-le vous-même :
# No spaces are allowed in the variable
first string value = "First string"
File "<ipython-input-1-2a2f77c0b400>", line 2
first string value = "First string"
^
SyntaxError: invalid syntax
# Cannot start with a number
1st_string_value = "First String"
File "<ipython-input-2-79b210888e10>", line 2
1st_string_value = "First String"
^
SyntaxError: invalid syntax
# Cannot be a keyword
True = "True"
File "<ipython-input-3-5d4d2170e79c>", line 3
True = "True"
^
SyntaxError: can't assign to keyword
Champ d'application variable
Maintenant que vous savez comment initialiser une variable. Parlons de la portée de ces variables. Toutes les variables ne sont pas accessibles depuis n'importe quel endroit du programme. La partie d'un programme où une variable est accessible est appelée sa portée. Il existe quatre grands types de champs d'application variables et c'est la base de la règle LEGB. LEGB signifie Local -> Enclosing -> Global -> Built-in.
En savoir plus sur les lunettes de visée...
Champ d'application local
Chaque fois que vous définissez une variable dans une fonction, sa portée se limite UNIQUEMENT à la fonction. Il est accessible à partir du moment où il est défini jusqu'à la fin de la fonction et existe tant que la fonction est en cours d'exécution(Source). Cela signifie que sa valeur ne peut pas être modifiée ni même consultée depuis l'extérieur de la fonction. Prenons un exemple simple :
def print_number():
first_num = 1
# Print statement 1
print("The first number defined is: ", first_num)
print_number()
# Print statement 2
print("The first number defined is: ", first_num)
The first number defined is: 1
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-10-17d580e01222> in <module>
6 print_number()
7 # Print statement 2
----> 8 print("The first number defined is: ", first_num)
NameError: name 'first_num' is not defined
Nous avons pu imprimer la variable first_num
en appelant la fonction print_number()
(# Instruction d'impression 1). Mais lorsque l'on essaie d'accéder à la même variable et de l'imprimer en dehors de la fonction (# Print statement 2), on obtient NameError
. En effet, le site first_num
est "local" à la fonction - il ne peut donc pas être atteint depuis l'extérieur du corps de la fonction.
Champ d'application
Que se passe-t-il si nous avons une fonction imbriquée (fonction définie à l'intérieur d'une autre fonction) ? Comment le champ d'application change-t-il ? Voyons cela à l'aide d'un exemple.
def outer():
first_num = 1
def inner():
second_num = 2
# Print statement 1 - Scope: Inner
print("first_num from outer: ", first_num)
# Print statement 2 - Scope: Inner
print("second_num from inner: ", second_num)
inner()
# Print statement 3 - Scope: Outer
print("second_num from inner: ", second_num)
outer()
first_num from outer: 1
second_num from inner: 2
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-4-13943a1eb01e> in <module>
11 print("second_num from inner: ", second_num)
12
---> 13 outer()
<ipython-input-4-13943a1eb01e> in outer()
9 inner()
10 # Print statement 3 - Scope: Outer
---> 11 print("second_num from inner: ", second_num)
12
13 outer()
NameError: name 'second_num' is not defined
Vous avez une erreur ? En effet, vous ne pouvez pas accéder à second_num
à partir de outer()
(# Imprimer l'énoncé 3). Elle n'est pas définie dans le cadre de cette fonction. Cependant, vous pouvez accéder à first_num
à partir de inner()
(# Imprimer l'énoncé 1), parce que le champ d'application de first_num
est plus large, il se trouve à l'intérieur de outer()
.
Il s'agit d'une portée englobante. Les variables de Outer
ont une portée plus large et sont accessibles à partir de la fonction englobante inner()
.
Champ d'application mondial
C'est peut-être le champ d'application le plus facile à comprendre. Chaque fois qu'une variable est définie en dehors d'une fonction, elle devient une variable globale et son champ d'application s'étend à n'importe quel endroit du programme. Cela signifie qu'il peut être utilisé par n'importe quelle fonction.
greeting = "Hello"
def greeting_world():
world = "World"
print(greeting, world)
def greeting_name(name):
print(greeting, name)
greeting_world()
greeting_name("Samuel")
Hello World
Hello Samuel
Portée intégrée
Il s'agit du champ d'application le plus large qui soit ! Tous les mots-clés spéciaux réservés relèvent de ce champ d'application. Nous pouvons appeler les mots-clés n'importe où dans notre programme sans avoir à les définir avant de les utiliser.
Les mots-clés sont simplement des mots spéciaux réservés. Ils sont conservés à des fins spécifiques et ne peuvent être utilisés à d'autres fins dans le programme.
Il s'agit des mots-clés en Python :
Règle LEGB
LEGB (Local -> Enclosing -> Global -> Built-in) est la logique suivie par un interprète Python lorsqu'il exécute votre programme.
Supposons que vous appeliez print(x)
à l'intérieur de inner()
, qui est une fonction imbriquée dans outer()
. Ensuite, Python cherchera d'abord à savoir si "x" a été défini localement dans inner()
. Si ce n'est pas le cas, la variable définie dans outer()
sera utilisée. Il s'agit de la fonction englobante. S'il n'a pas non plus été défini à cet endroit, l'interpréteur Python remontera d'un niveau supplémentaire - à la portée globale. Au-dessus, vous ne trouverez que la portée intégrée, qui contient des variables spéciales réservées à Python lui-même.
Jusqu'à présent, tout va bien !
Reprenons ensuite quelques exemples précédents pour voir s'ils peuvent poser des problèmes lorsque le cas d'utilisation devient légèrement plus complexe.
Scénario 1 : Champ d'application mondial
Vous vous souvenez de la fonction greeting_world()
de tout à l'heure ? Supposons que vous souhaitiez modifier la variable globale greeting
("Hello") pour définir une nouvelle valeur ("Hi") pour le message d'accueil, de sorte que greeting_world()
imprime "Hi World"
greeting = "Hello"
def change_greeting(new_greeting):
greeting = new_greeting
def greeting_world():
world = "World"
print(greeting, world)
change_greeting("Hi")
greeting_world()
Hello World
Eh bien... cela ne s'est pas passé comme prévu ! Pourquoi ?
En effet, lorsque nous avons fixé la valeur de greeting
à "Hi", nous avons créé une nouvelle variable locale greeting
dans le champ d'application de change_greeting()
. Elle n'a rien changé à la situation mondiale greeting
. C'est là que le mot-clé global s'avère utile.
Mot-clé global
Avec global, vous indiquez à Python d'utiliser la variable définie globalement au lieu d'en créer une localement. Pour utiliser le mot-clé, il suffit de taper "global", suivi du nom de la variable. Voyons cela en action dans le scénario 1.
greeting = "Hello"
def change_greeting(new_greeting):
global greeting
greeting = new_greeting
def greeting_world():
world = "World"
print(greeting, world)
change_greeting("Hi")
greeting_world()
Hi World
Cela a fonctionné ! Passons au scénario suivant...
Scénario 2 : Champ d'application
Nous examinons ici les fonctions imbriquées outer()
et inner()
de l'exemple Enclosing Scope. Essayons de faire passer la valeur de first_num
de 1 à 0 à partir de inner()
.
def outer():
first_num = 1
def inner():
first_num = 0
second_num = 1
print("inner - second_num is: ", second_num)
inner()
print("outer - first_num is: ", first_num)
outer()
inner - second_num is: 1
outer - first_num is: 1
Ce n'est pas toujours aussi simple, n'est-ce pas ? À cette fin, nous utilisons un mot-clé non local dans Python.
Mot clé non local
Il s'agit d'un autre mot-clé pratique qui nous permet de travailler de manière plus souple et plus ordonnée avec des champs d'application variables. Le mot-clé non local est utile dans les fonctions imbriquées. Elle fait en sorte que la variable fasse référence à la variable précédemment liée dans l'étendue la plus proche. En d'autres termes, cela empêchera la variable d'essayer de se lier d'abord localement et l'obligera à passer à un niveau "supérieur". La syntaxe est similaire à celle du mot-clé global.
def outer():
first_num = 1
def inner():
nonlocal first_num
first_num = 0
second_num = 1
print("inner - second_num is: ", second_num)
inner()
print("outer - first_num is: ", first_num)
outer()
inner - second_num is: 1
outer - first_num is: 0
Et voilà !
Conclusion
Vous savez maintenant ce qu'est la portée des variables de Python, la règle LEGB, et comment vous devez utiliser les mots-clés globaux et non locaux. Vous pourrez facilement manipuler des variables dans des fonctions imbriquées, sans aucun problème. Pour en savoir plus sur la programmation en Python, vous devriez absolument jeter un coup d'œil au cours Intro to Python for Data Science de DataCamp. Il s'agit d'un cours interactif qui couvre toutes les bases : des variables aux calculs en passant par les listes, les fonctions et les paquets.
En savoir plus sur Python
cours
Introduction à la science des données en Python
cours