Variables Locales, Globales et Nonlocal en Python : Portee et Conditionnels

Comprenez la portee des variables en Python : locales, globales et nonlocal. Guide pratique avec conditionnels if-elif-else et operateurs logiques.

Mahmoud DEVO
Mahmoud DEVO
December 27, 2025 7 min read
Variables Locales, Globales et Nonlocal en Python : Portee et Conditionnels

Manipulation de Variables et Conditionnels en Python

Introduction

La comprehension de la portee des variables (scope) est l’une des competences les plus importantes pour tout developpeur Python. Que vous soyez debutant ou developpeur experimente, maitriser les concepts de variables locales, globales et nonlocal vous permettra d’ecrire un code plus propre, plus maintenable et exempt de bugs subtils lies a la visibilite des donnees.

Dans cet article approfondi, nous allons explorer en detail comment Python gere la portee des variables a travers les differents niveaux d’imbrication de fonctions. Nous verrons egalement comment les conditionnels if-elif-else permettent de controler le flux d’execution de vos programmes, et comment les operateurs logiques vous aident a construire des expressions conditionnelles complexes.

La regle LEGB (Local, Enclosing, Global, Built-in) de Python definit l’ordre dans lequel l’interpreteur recherche les variables. Comprendre cette regle est essentiel pour eviter les erreurs de type UnboundLocalError ou les comportements inattendus dans vos fonctions imbriquees.

Variables Locales, Globales et Non-Locales

En Python, il existe trois types de variables selon leur portee : locales, globales et non locales. Comprendre ces distinctions est fondamental pour ecrire du code robuste et eviter les effets de bord inattendus.

Variables Locales

Les variables locales sont definies a l’interieur d’une fonction et ne sont accessibles que dans cette fonction. Elles sont creees lors de l’appel de la fonction et detruites a sa fin.

def calculer_somme(a, b):
    resultat = a + b  # Variable locale
    temp = resultat * 2  # Autre variable locale
    return resultat

print(calculer_somme(5, 3))  # Affiche: 8
# print(resultat)  # Erreur! 'resultat' n'existe pas ici

Variables Globales

Les variables globales sont definies au niveau du module (en dehors de toute fonction) et peuvent etre lues depuis n’importe ou dans le code. Pour les modifier depuis une fonction, il faut utiliser le mot-cle global.

compteur_global = 0

def incrementer_compteur():
    global compteur_global  # Declaration obligatoire pour modifier
    compteur_global += 1
    print(f"Compteur: {compteur_global}")

def lire_compteur():
    # Lecture possible sans 'global'
    print(f"Valeur actuelle: {compteur_global}")

incrementer_compteur()  # Compteur: 1
incrementer_compteur()  # Compteur: 2
lire_compteur()         # Valeur actuelle: 2

Variables Non-Locales (nonlocal)

Le mot-cle nonlocal, introduit en Python 3, permet d’acceder aux variables d’une fonction englobante (enclosing scope). C’est particulierement utile dans les closures et les fonctions imbriquees.

def creer_compteur():
    compte = 0  # Variable de la fonction englobante

    def incrementer():
        nonlocal compte  # Reference la variable de creer_compteur()
        compte += 1
        return compte

    def obtenir_valeur():
        return compte  # Lecture sans nonlocal

    return incrementer, obtenir_valeur

inc, get = creer_compteur()
print(inc())  # 1
print(inc())  # 2
print(get())  # 2

Exemple Pratique : Gestionnaire de Configuration

Voici un exemple concret utilisant les trois types de portee :

CONFIG_GLOBALE = {"debug": False, "version": "1.0"}

def creer_gestionnaire_config():
    config_locale = CONFIG_GLOBALE.copy()
    modifications = 0

    def modifier_config(cle, valeur):
        nonlocal modifications
        config_locale[cle] = valeur
        modifications += 1
        print(f"Config modifiee ({modifications} fois)")

    def activer_debug_global():
        global CONFIG_GLOBALE
        CONFIG_GLOBALE["debug"] = True
        print("Debug global active")

    def afficher_config():
        print(f"Locale: {config_locale}")
        print(f"Globale: {CONFIG_GLOBALE}")

    return modifier_config, activer_debug_global, afficher_config

modifier, debug_global, afficher = creer_gestionnaire_config()
modifier("theme", "dark")
afficher()
debug_global()
afficher()

Conditionnels if-elif-else

Les conditionnels if-elif-else constituent le mecanisme principal de controle de flux en Python. Ils permettent d’executer differents blocs de code selon des conditions specifiques.

Syntaxe de Base

age = 25

if age < 18:
    categorie = "Mineur"
    tarif = 5
elif age < 65:
    categorie = "Adulte"
    tarif = 10
else:
    categorie = "Senior"
    tarif = 7

print(f"{categorie}: {tarif} euros")

Expressions Conditionnelles (Ternaire)

Python offre une syntaxe concise pour les conditions simples :

# Forme classique
if age >= 18:
    statut = "majeur"
else:
    statut = "mineur"

# Forme ternaire equivalente
statut = "majeur" if age >= 18 else "mineur"

# Ternaire imbrique (a utiliser avec moderation)
note = 85
mention = "Excellent" if note >= 90 else "Bien" if note >= 70 else "Passable"

Conditions Multiples avec Tuples

def obtenir_tarif(jour, heure):
    # Verification de conditions multiples
    if (jour in ["samedi", "dimanche"]) and (10 <= heure <= 18):
        return "Tarif weekend"
    elif jour == "mercredi" and heure < 14:
        return "Tarif enfant"
    else:
        return "Tarif normal"

print(obtenir_tarif("samedi", 14))  # Tarif weekend

Operateurs Logiques

Les operateurs logiques and, or et not permettent de combiner plusieurs conditions pour creer des expressions complexes.

Operateurs de Base

utilisateur_connecte = True
est_admin = False
compte_verifie = True

# AND : toutes les conditions doivent etre vraies
if utilisateur_connecte and compte_verifie:
    print("Acces autorise")

# OR : au moins une condition doit etre vraie
if est_admin or utilisateur_connecte:
    print("Afficher le tableau de bord")

# NOT : inverse la valeur booleenne
if not est_admin:
    print("Acces administrateur refuse")

# Combinaison
if utilisateur_connecte and (est_admin or compte_verifie):
    print("Acces complet")

Court-Circuit (Short-Circuit Evaluation)

Python utilise l’evaluation en court-circuit, ce qui peut etre exploite pour ecrire du code plus elegant :

# and retourne la premiere valeur fausse ou la derniere valeur
utilisateur = None
nom = utilisateur and utilisateur.get("nom", "Inconnu")
print(nom)  # None (court-circuit, utilisateur est falsy)

# or retourne la premiere valeur vraie
nom_affiche = nom or "Visiteur"
print(nom_affiche)  # Visiteur

# Utilisation pratique pour les valeurs par defaut
def saluer(nom=None):
    nom = nom or "Ami"
    print(f"Bonjour, {nom}!")

saluer()          # Bonjour, Ami!
saluer("Alice")   # Bonjour, Alice!

Comparaisons de Valeurs

Python offre des operateurs de comparaison riches et permet meme les comparaisons chainees.

Operateurs de Comparaison

x, y = 10, 20

# Comparaisons simples
print(x == y)   # False (egalite)
print(x != y)   # True (difference)
print(x < y)    # True (inferieur)
print(x <= y)   # True (inferieur ou egal)
print(x > y)    # False (superieur)
print(x >= y)   # False (superieur ou egal)

# Comparaisons chainees (specifique a Python)
age = 25
if 18 <= age < 65:
    print("Adulte actif")

# Equivalent a:
if age >= 18 and age < 65:
    print("Adulte actif")

Comparaison d’Identite vs Egalite

liste1 = [1, 2, 3]
liste2 = [1, 2, 3]
liste3 = liste1

# == compare les valeurs
print(liste1 == liste2)  # True

# is compare l'identite (meme objet en memoire)
print(liste1 is liste2)  # False
print(liste1 is liste3)  # True

# Utilisation correcte de 'is' avec None
valeur = None
if valeur is None:  # Prefere a 'valeur == None'
    print("Valeur non definie")

Bonnes Pratiques

Voici les recommandations essentielles pour gerer efficacement les variables et les conditionnels en Python.

1. Minimiser l’Utilisation des Variables Globales

Les variables globales rendent le code difficile a tester et a maintenir. Privilegiez le passage de parametres explicites.

# A eviter
total = 0
def ajouter(valeur):
    global total
    total += valeur

# Preferer
def ajouter(total, valeur):
    return total + valeur

2. Utiliser des Noms de Variables Explicites

Un bon nom de variable documente votre code automatiquement.

# A eviter
if x > 18 and y == True:
    pass

# Preferer
if age_utilisateur > AGE_MAJORITE and compte_est_verifie:
    pass

3. Privilegier les Conditions Positives

Les conditions positives sont plus faciles a lire et a comprendre.

# A eviter
if not utilisateur_inactif:
    traiter_requete()

# Preferer
if utilisateur_actif:
    traiter_requete()

4. Utiliser les Guard Clauses

Les guard clauses reduisent l’imbrication et ameliorent la lisibilite.

# A eviter (imbrication profonde)
def traiter_commande(commande):
    if commande:
        if commande.est_valide():
            if commande.paiement_ok():
                return executer_commande(commande)
    return None

# Preferer (guard clauses)
def traiter_commande(commande):
    if not commande:
        return None
    if not commande.est_valide():
        return None
    if not commande.paiement_ok():
        return None
    return executer_commande(commande)

5. Utiliser match-case pour les Conditions Multiples (Python 3.10+)

def obtenir_type_fichier(extension):
    match extension.lower():
        case ".py":
            return "Python"
        case ".js" | ".ts":
            return "JavaScript/TypeScript"
        case ".md":
            return "Markdown"
        case _:
            return "Inconnu"

Pieges Courants

Evitez ces erreurs frequentes qui peuvent causer des bugs difficiles a debugger.

1. Oublier la Declaration global ou nonlocal

compteur = 0

def incrementer():
    compteur += 1  # UnboundLocalError!

# Solution
def incrementer():
    global compteur
    compteur += 1

2. Confondre == et is

# Piege avec les entiers
a = 1000
b = 1000
print(a == b)  # True
print(a is b)  # False (peut varier selon l'implementation)

# Regle: utilisez 'is' uniquement pour None, True, False
if valeur is None:  # Correct
    pass

3. Modifier une Liste Globale sans global

ma_liste = [1, 2, 3]

def ajouter_element():
    ma_liste.append(4)  # Fonctionne sans global!
    # Mais...
    ma_liste = [5, 6]  # Cree une variable locale!

# Comprendre: global est necessaire pour reassigner, pas pour muter

4. Conditions Toujours Vraies ou Fausses

# Piege: comparaison incorrecte
nom = "Alice"
if nom == "Alice" or "Bob":  # Toujours True!
    print("Trouve")

# Correct
if nom == "Alice" or nom == "Bob":
    print("Trouve")

# Ou mieux
if nom in ("Alice", "Bob"):
    print("Trouve")

Conclusion

La maitrise de la portee des variables et des conditionnels est fondamentale pour tout developpeur Python. Dans cet article, nous avons explore en profondeur :

  • Les trois types de portee : locale, globale et nonlocal, avec leurs cas d’usage specifiques
  • La regle LEGB : l’ordre de resolution des variables par l’interpreteur Python
  • Les conditionnels if-elif-else : y compris les expressions ternaires et les conditions chainees
  • Les operateurs logiques : and, or, not et leur comportement en court-circuit
  • Les comparaisons : egalite vs identite et les comparaisons chainees

En appliquant les bonnes pratiques presentees et en evitant les pieges courants, vous ecrirez du code Python plus robuste, plus lisible et plus facile a maintenir.

Prochaines Etapes

Pour approfondir vos connaissances, explorez ces sujets connexes :

  • Closures et decorateurs : utilisation avancee de nonlocal
  • Pattern matching : match-case en Python 3.10+
  • Context managers : gestion de portee avec with
  • Type hints : documentation des types de variables
Advertisement

In-Article Ad

Dev Mode

Share this article

Mahmoud DEVO

Mahmoud DEVO

Senior Full-Stack Developer

I'm a passionate full-stack developer with 10+ years of experience building scalable web applications. I write about Vue.js, Node.js, PostgreSQL, and modern DevOps practices.

Enjoyed this article?

Subscribe to get more tech content delivered to your inbox.

Related Articles