Comprendre si __name__ == ‘__main__’ en Python

Dans ce guide, vous comprendrez la fonctionnalité et la signification de if __name__ == ‘__main__’ en Python.

Avez-vous déjà parcouru une base de code Python avec différents modules ?

Si oui, vous auriez probablement rencontré if __name__ == ‘__main__’ conditionnel dans un ou plusieurs modules. Au cours des prochaines minutes, nous allons démystifier ce que signifie le conditionnel ci-dessus et examiner un exemple où cela peut être utile.

Commençons!

Quelle est la signification de __name__ en Python ?

En Python, un module est un fichier .py qui contient des définitions de fonctions, un ensemble d’expressions à évaluer, etc. Par exemple, si nous avons un fichier nommé hello_world.py, nous l’appelons le fichier hello_world.py ou le module hello_world.

Lorsque vous exécutez un module Python, l’interpréteur Python définit les valeurs de quelques variables spéciales avant l’exécution : __name__ en fait partie. La clé pour comprendre la signification de __name__ est de comprendre comment les importations fonctionnent en Python.

📁 Téléchargez le code de cette section ici.

Rendez-vous dans le dossier exemple-1. Nous avons le fichier module1.py. La variable __name__ se trouve dans l’espace de noms du module actuel.

Ce module affiche une ligne suivie de la valeur de la variable __name__.

# example-1/module1.py
print("This is module1.")
print(f"The __name__ variable of module 1 is: {__name__}.")

Maintenant, exécutons module1 à partir de la ligne de commande.

$ python module1.py

Dans la sortie, nous voyons que la variable __name__ est définie sur __main__.

This is module1.
The __name__ variable of module 1 is: __main__.

Importation de modules en Python

En plus d’exécuter un module Python, vous souhaiterez parfois utiliser les fonctionnalités d’un autre module Python à l’intérieur du module actuel. Python facilite cela grâce aux importations.

Les importations vous permettent de réutiliser la fonctionnalité d’un autre module, en l’important dans la portée du module actuel, sans avoir à réécrire le code.

Le fichier module2.py contient les éléments suivants. Nous avons importé module1 à l’intérieur. module2.

# example-1/module2.py

import module1 # module1 is imported

print(f"This is module2")
print(f"The __name__ variable of module2 is: {__name__}.")

Nous exécutons module2.py et observons la sortie.

$ python module2.py

Dans la sortie ci-dessous :

  • Nous voyons que module1 est exécuté sous le capot lorsque nous l’importons dans module2, et la sortie correspondante est imprimée.
  • Mais cette fois, la variable __name__ n’est pas __main__ mais module1.
  • Parce que nous avons exécuté module2 directement, la variable __name__ correspondant au module est maintenant __main__.
Output

This is module1.
The __name__ variable of module 1 is: module1.
This is module2
The __name__ variable of module2 is: __main__.

💡 Idée clé :

– Si un module est exécuté directement, sa variable __name__ est définie sur est égal à __main__.

– Si un module est importé dans un autre module, son __name__ est défini sur le nom du module.

Exemple de if __name__==’__main__’ en Python

Dans la section, nous verrons un cas d’utilisation pratique du conditionnel if __name__ == ‘__main__’. Nous allons définir une fonction simple, puis écrire des tests unitaires pour vérifier si la fonction fonctionne comme prévu.

📁 Téléchargez le code et suivez-le.

Le code de cette section se trouve dans le dossier example-2.

Ici, add.py est un fichier Python qui contient la définition de la fonction add_ab(). La fonction add_ab() prend deux nombres quelconques et renvoie leur somme.

# example-2/add.py

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

Nous allons utiliser le module unittest de Python pour tester la fonction add_ab().

Écrire des cas de test pour une fonction Python

Regardez l’extrait de code ci-dessous, contenant le contenu du module test_add.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)
    

Le code ci-dessus effectue les opérations suivantes :

  • Importe le module unittest intégré de Python
  • Importe la fonction add_ab() du module d’ajout
  • Définit la classe de test TestAdd et un ensemble de cas de test en tant que méthodes au sein de la classe de test

Pour configurer des tests unitaires pour votre code, vous devez d’abord définir une classe de test qui hérite de unittest.TestCase. Tous les cas de test doivent être spécifiés en tant que méthodes à l’intérieur de la classe et doivent commencer par test_.

Remarque : Si vous ne nommez pas les méthodes en tant que test_, vous verrez que les tests correspondants ne seront pas détectés et, par conséquent, ne s’exécuteront pas.

Essayons maintenant d’exécuter le module test_add depuis le terminal.

$ python test_add.py

Vous verrez qu’il n’y a pas de sortie et qu’aucun des tests n’a été exécuté.

Pourquoi est-ce le cas ?🤔

En effet, pour exécuter les tests unitaires, vous devez exécuter unittest en tant que module principal lors de l’exécution de test_add.py, à l’aide de la commande ci-dessous.

$ python -m unittest test_add.py

Lors de l’exécution de la commande détaillée ci-dessus, nous constatons que les trois tests ont été exécutés avec succès.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Cependant, il sera pratique d’exécuter les tests lorsque ce module test_add sera exécuté, n’est-ce pas ? Apprenons à le faire dans la section suivante.

Utilisation de if __name__ == ‘__main__’ pour exécuter unittest en tant que module principal

Si vous souhaitez exécuter tous les tests unitaires lorsque le module s’exécute directement, vous pouvez ajouter le conditionnel.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)

# Run unittest as the main module
if __name__ == '__main__':
        unittest.main()

La condition dans l’extrait de code ci-dessus indique à l’interpréteur Python : si ce module est exécuté directement, exécutez le code à l’intérieur. unittest.main().

Vous pouvez exécuter le module test_add après avoir ajouté les deux lignes de code ci-dessus.

$ python test_add.py

▶️ L’exécution directe du module d’ajout de test exécute désormais les trois tests que nous avons définis.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

La sortie OK ci-dessus indique que tous les tests ont été exécutés avec succès. Les trois points… indiquent que trois tests ont été exécutés et tous réussis.

Maintenant, changeons la valeur de retour attendue test_add_1_minus7 en 8. Comme la fonction renvoie – 6 dans ce cas, il devrait y avoir un test qui échoue.

def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), 8)

Comme on le voit dans la sortie ci-dessous, nous obtenons .F., parmi les trois tests, le modèle un a échoué (le deuxième test), et dans le traçage, nous obtenons une AssertionError indiquant – 6 != 8.

Output
.F.
======================================================================
FAIL: test_add_1_minus7 (__main__.TestAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_add.py", line 12, in test_add_1_minus7
    self.assertEqual(add_ab(1,-7), 8)
AssertionError: -6 != 8

----------------------------------------------------------------------
Ran 3 tests in 0.021s

FAILED (failures=1)

Une chose importante à noter est que les tests ne s’exécutent pas nécessairement dans le même ordre dans lequel ils sont spécifiés dans la classe de test. Dans l’exemple ci-dessus, test_add_1_minus7 est défini comme la troisième méthode de la classe de test, mais le test correspondant a été exécuté en deuxième.

Résumé

J’espère que ce tutoriel vous a aidé à comprendre comment le conditionnel if __name__ == ‘__main__’ fonctionne en Python.

Voici un bref récapitulatif des principaux points à retenir :

  • L’interpréteur Python définit la variable __name__ avant d’exécuter le script Python.
  • Lorsque vous exécutez un module directement, la valeur de __name__ est __main__.
  • Lorsque vous importez un module dans un autre script Python, la valeur de __name__ est le nom du module.
  • Vous pouvez utiliser if __name__ == ‘__main__’ pour contrôler l’exécution et quelles parties du module s’exécutent respectivement lors des exécutions directes et importées.

Ensuite, consultez ce guide détaillé sur les ensembles Python. Bon apprentissage !🎉