Qu'est-ce que __name__ en Python ?-

Découvrez __name__ en Python : son rôle, la condition if __name__ == '__main__', ses cas d'utilisation concrets et les bonnes pratiques pour structurer vos programmes.
9 min de lecture
Believemy logo

Définition de __name__ en Python

En Python, __name__ est une variable spéciale intégrée (aussi appelée dunder attribute, pour "double underscore") qui est automatiquement définie par l'interpréteur Python dans chaque module. Sa valeur dépend du contexte d'exécution du fichier :

  • Si le fichier est exécuté directement (comme script principal), __name__ vaut la chaîne "__main__".
  • Si le fichier est importé en tant que module depuis un autre fichier, __name__ vaut le nom du module (c'est-à-dire le nom du fichier sans l'extension .py).

Cette variable est au cœur de l'une des conventions les plus importantes de Python : le fameux bloc if __name__ == "__main__". Si vous suivez notre formation complète sur Python, vous découvrirez que cette notion est essentielle pour écrire du code professionnel et réutilisable.

Bon à savoir

__name__ fait partie des attributs spéciaux de Python (comme __doc__, __file__, __package__). On les appelle dunder attributes car ils sont entourés de doubles underscores (double underscores → dunder).

 

Comment fonctionne __name__ ?

Pour bien comprendre __name__, il faut visualiser ce qui se passe lorsque Python exécute un fichier. L'interpréteur attribue automatiquement des métadonnées à chaque module chargé, et __name__ en fait partie.

Exécution directe d'un script

Lorsque vous lancez un fichier Python directement depuis la ligne de commande (par exemple python mon_script.py), l'interpréteur définit __name__ à "__main__" pour ce fichier :

PYTHON
# fichier : mon_script.py
print(__name__)

Résultat en exécutant python mon_script.py :

PYTHON
__main__

 

Importation en tant que module

Maintenant, si vous importez ce même fichier depuis un autre script, la valeur de __name__ change :

PYTHON
# fichier : autre_script.py
import mon_script

Résultat en exécutant python autre_script.py :

PYTHON
mon_script

Comme vous pouvez le constater, __name__ vaut désormais "mon_script" (le nom du fichier sans .py) et non plus "__main__". C'est cette distinction qui rend __name__ si puissant.

 

Le bloc if __name__ == "__main__"

La construction if __name__ == "__main__" est probablement le pattern le plus courant en Python. Vous le retrouverez dans la quasi-totalité des projets professionnels. Son rôle est simple : exécuter un bloc de code uniquement quand le fichier est lancé directement, et pas quand il est importé.

Exemple fondamental

PYTHON
# fichier : calculatrice.py

def additionner(a, b):
    return a + b

def soustraire(a, b):
    return a - b

def multiplier(a, b):
    return a * b

if __name__ == "__main__":
    # Ce bloc ne s'exécute que si le fichier est lancé directement
    print("Test de la calculatrice")
    print(f"3 + 5 = {additionner(3, 5)}")
    print(f"10 - 4 = {soustraire(10, 4)}")
    print(f"6 * 7 = {multiplier(6, 7)}")

Lorsque vous exécutez python calculatrice.py, vous obtenez :

PYTHON
Test de la calculatrice
3 + 5 = 8
10 - 4 = 6
6 * 7 = 42

Mais si vous importez ce module depuis un autre fichier :

PYTHON
# fichier : application.py
import calculatrice

resultat = calculatrice.additionner(100, 200)
print(resultat)  # 300

Seul 300 s'affiche. Le bloc de test de la calculatrice ne s'exécute pas, car __name__ vaut "calculatrice" et non "__main__".

 

Pourquoi est-ce si important ?

Sans cette garde, chaque importation déclencherait l'exécution de tout le code « libre » du module. Imaginez un module qui lance un serveur web ou effectue des calculs lourds : vous ne voudriez pas que cela se produise à chaque import. Le bloc if __name__ == "__main__" vous donne le contrôle total sur ce qui s'exécute et quand.

 

Exemples pratiques avancés

Structurer un projet avec __name__

Dans un projet bien structuré, chaque module peut être à la fois une bibliothèque de fonctions et un script exécutable. Voici un exemple plus complet :

PYTHON
# fichier : utils.py

def formater_nom(prenom, nom):
    """Formate un nom complet en capitalisant correctement."""
    return f"{prenom.capitalize()} {nom.upper()}"

def valider_email(email):
    """Vérifie basiquement qu'un email contient un @."""
    return "@" in email and "." in email

def generer_identifiant(prenom, nom):
    """Génère un identifiant unique basé sur le nom."""
    return f"{prenom.lower()}.{nom.lower()}"


if __name__ == "__main__":
    # Tests manuels rapides
    print("=== Tests du module utils ===")
    
    nom_formate = formater_nom("jean", "dupont")
    print(f"Nom formaté : {nom_formate}")
    
    email_valide = valider_email("jean@example.com")
    print(f"Email valide : {email_valide}")
    
    identifiant = generer_identifiant("Jean", "Dupont")
    print(f"Identifiant : {identifiant}")

Vous pouvez ainsi tester rapidement votre module avec python utils.py, tout en l'important proprement ailleurs avec import utils.

 

Utilisation avec une fonction main()

Une convention très répandue consiste à définir une fonction def nommée main() et à l'appeler dans le bloc de garde. Cela rend le code plus propre et plus testable :

PYTHON
# fichier : app.py
import sys

def traiter_donnees(fichier):
    """Traite les données d'un fichier."""
    print(f"Traitement de {fichier}...")
    # Logique de traitement ici
    return True

def afficher_aide():
    """Affiche l'aide du programme."""
    print("Usage : python app.py ")
    print("Options :")
    print("  -h, --help    Afficher cette aide")

def main():
    """Point d'entrée principal du programme."""
    if len(sys.argv) < 2:
        afficher_aide()
        sys.exit(1)
    
    fichier = sys.argv[1]
    
    if fichier in ("-h", "--help"):
        afficher_aide()
    else:
        succes = traiter_donnees(fichier)
        if succes:
            print("Traitement terminé avec succès !")

if __name__ == "__main__":
    main()

Cette approche est recommandée car elle permet de réutiliser la logique de main() dans des tests unitaires sans avoir à exécuter le script entier.

 

__name__ dans les classes et les fonctions

Il est important de noter que __name__ existe aussi comme attribut des class et des fonctions :

PYTHON
class Vehicule:
    pass

def accelerer():
    pass

print(Vehicule.__name__)  # Vehicule
print(accelerer.__name__)  # accelerer

# Utile pour le débogage et la journalisation
def log_appel(func):
    def wrapper(*args, **kwargs):
        print(f"Appel de la fonction : {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_appel
def calculer_total(prix, quantite):
    return prix * quantite

calculer_total(10, 5)
# Affiche : Appel de la fonction : calculer_total

Ici, __name__ renvoie le nom de la classe ou de la fonction sous forme de chaîne de caractères, ce qui est extrêmement utile pour le docstring, le débogage et la métaprogrammation.

 

__name__ et les packages

Dans le contexte des packages (dossiers contenant un fichier __init__.py), __name__ reflète le chemin complet du module :

PYTHON
# Structure :
# mon_projet/
#   __init__.py
#   core/
#     __init__.py
#     moteur.py

# Dans mon_projet/core/moteur.py :
print(__name__)  
# Quand importé : "mon_projet.core.moteur"
# Quand exécuté directement : "__main__"

 

Tableau récapitulatif

Contexte d'exécutionValeur de __name__Exemple
Script exécuté directement"__main__"python script.py
Module importéNom du moduleimport script → "script"
Module dans un packageChemin completimport pkg.mod → "pkg.mod"
Attribut d'une classeNom de la classeMaClasse.__name__ → "MaClasse"
Attribut d'une fonctionNom de la fonctionma_func.__name__ → "ma_func"

 

Bonnes pratiques

Voici les règles à suivre pour tirer le meilleur parti de __name__ dans vos projets Python :

1. Toujours utiliser le bloc de garde

Chaque fichier Python susceptible d'être importé ET exécuté devrait contenir un bloc if __name__ == "__main__". C'est une convention universelle et une marque de code professionnel.

PYTHON
# ✅ Bonne pratique
def ma_fonction():
    return "Résultat"

if __name__ == "__main__":
    print(ma_fonction())

# ❌ Mauvaise pratique
def ma_fonction():
    return "Résultat"

print(ma_fonction())  # S'exécute aussi à l'importation !

 

2. Déléguer à une fonction main()

Plutôt que de placer toute la logique dans le bloc if, créez une fonction main() dédiée. Cela facilite les tests et améliore la lisibilité.

PYTHON
# ✅ Recommandé
def main():
    # Toute la logique ici
    pass

if __name__ == "__main__":
    main()

 

3. Utiliser __name__ pour le logging

L'utilisation de __name__ dans la configuration du print et du module logging est une pratique standard :

PYTHON
import logging

# Crée un logger avec le nom du module courant
logger = logging.getLogger(__name__)

def ma_fonction():
    logger.info("Fonction exécutée")
    # Le log affichera le nom du module automatiquement

Cette approche est puissante car elle permet de tracer exactement quel module a émis un message de log, ce qui est indispensable dans les projets de grande envergure.

 

4. Ne pas modifier __name__

Attention

Bien qu'il soit techniquement possible de modifier la valeur de __name__, vous ne devriez jamais le faire. Cette variable est gérée par l'interpréteur Python et la modifier peut entraîner des comportements imprévisibles.

 

5. Séparer définitions et exécution

Placez toutes vos définitions de fonctions, class et constantes en haut du fichier. Le bloc if __name__ == "__main__" doit être le dernier élément du fichier :

PYTHON
# 1. Imports
import os
import sys

# 2. Constantes
VERSION = "1.0.0"

# 3. Classes et fonctions
class Application:
    pass

def demarrer():
    pass

# 4. Point d'entrée (toujours en dernier)
if __name__ == "__main__":
    demarrer()

 

Erreurs courantes à éviter

Voici les pièges les plus fréquents liés à __name__ :

Oublier les guillemets autour de __main__

PYTHON
# ❌ Erreur : __main__ sans guillemets n'existe pas comme variable
if __name__ == __main__:  # NameError !
    pass

# ✅ Correct : c'est une chaîne de caractères
if __name__ == "__main__":
    pass

 

Confondre __name__ du module et de la classe

PYTHON
class MonMoteur:
    pass

# __name__ au niveau du module = contexte d'exécution
print(__name__)  # "__main__" ou nom du module

# __name__ sur la classe = nom de la classe
print(MonMoteur.__name__)  # "MonMoteur"

 

Exécuter du code au niveau global sans garde

PYTHON
# ❌ Dangereux : ce code s'exécute à chaque import
connexion = creer_connexion_base_de_donnees()
resultat = requete_longue(connexion)

# ✅ Protégé par la garde
if __name__ == "__main__":
    connexion = creer_connexion_base_de_donnees()
    resultat = requete_longue(connexion)

 

Questions fréquentes

Question

Que signifie exactement if __name__ == "__main__" en Python ?

Cette condition vérifie si le fichier Python est exécuté directement (et non importé comme module). Quand vous lancez un fichier avec python fichier.py, l'interpréteur attribue la valeur "__main__" à la variable __name__ de ce fichier. La condition est donc vraie et le bloc de code s'exécute. En revanche, si ce fichier est importé par un autre script via import fichier, __name__ vaut "fichier" et le bloc est ignoré. C'est un mécanisme essentiel pour séparer le code réutilisable du code d'exécution.

 

Question

Peut-on avoir plusieurs blocs if __name__ == "__main__" dans un même fichier ?

Techniquement, oui, Python ne vous en empêchera pas. Cependant, c'est fortement déconseillé. La convention est d'avoir un seul bloc if __name__ == "__main__" placé à la toute fin du fichier. Avoir plusieurs blocs rend le code confus et difficile à maintenir. Si vous avez besoin d'exécuter plusieurs actions, regroupez-les dans une fonction main() unique.

 

Question

__name__ est-il obligatoire dans tous les fichiers Python ?

Non, __name__ n'est pas obligatoire. La variable existe toujours automatiquement, mais vous n'êtes pas obligé d'utiliser le bloc if __name__ == "__main__". Cependant, il est recommandé de l'ajouter dès que votre fichier contient du code qui ne devrait pas s'exécuter lors d'une importation. Pour les fichiers qui ne sont que des bibliothèques de def (fonctions) ou de class, c'est une bonne pratique d'inclure ce bloc pour y placer des tests rapides.

 

Question

Comment apprendre à bien utiliser __name__ et structurer ses projets Python ?

Pour maîtriser __name__ et toutes les conventions professionnelles de Python, nous vous recommandons de suivre notre formation dédiée à Python sur Believemy. Vous y apprendrez non seulement la syntaxe du langage, mais aussi les bonnes pratiques de structuration de projets, la gestion des modules et packages, et les patterns utilisés en entreprise. La pratique régulière avec des projets concrets est la meilleure façon d'intégrer ces concepts naturellement dans votre code.

Termes connexes

Découvrez notre glossaire Python

Parcourez les termes et définitions les plus couramment utilisés dans le domaine du développement avec Python.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.