Importer des Modules et des Packages en Python

PythonBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez les fondamentaux de l'organisation et de la réutilisation du code en Python en travaillant avec des modules et des paquets (packages). Nous commencerons par comprendre ce qu'est un module Python et comment son comportement d'exécution change selon qu'il est exécuté directement ou importé.

Vous pratiquerez ensuite les deux principales façons d'intégrer du code provenant de modules dans votre programme : l'instruction import pour charger un module entier et l'instruction from...import pour charger des fonctions ou des variables spécifiques. Enfin, vous apprendrez à structurer des modules connexes en un paquet afin de créer un projet bien organisé et évolutif. Tout le codage sera effectué dans le WebIDE, en utilisant des fichiers Python et le terminal.

Comprendre les Modules Python

Un module en Python est simplement un fichier contenant du code Python, qui possède une extension .py. Les modules vous permettent d'organiser logiquement votre code, le rendant plus facile à gérer et à réutiliser. Les fonctions, classes et variables définies dans un module peuvent être utilisées dans d'autres scripts.

Dans votre WebIDE, vous verrez un explorateur de fichiers sur le côté gauche. L'environnement du laboratoire a déjà créé un fichier nommé hello.py dans le répertoire ~/project.

Tout d'abord, ouvrez hello.py pour examiner son contenu. Il devrait contenir le code suivant :

print("This code runs on import or direct execution.")

if __name__ == "__main__":
    print("This code runs ONLY when the script is executed directly.")

Le bloc if __name__ == "__main__": est une construction spéciale en Python. La variable __name__ est une variable intégrée qui est évaluée à la valeur du nom du module courant. Lorsqu'un script Python est exécuté directement depuis la ligne de commande, sa valeur __name__ est définie sur la chaîne de caractères "__main__". Cette instruction if vous permet d'écrire du code qui ne s'exécutera que lorsque le fichier est exécuté comme programme principal, et non lorsqu'il est importé par un autre module.

Voyons cela en action. Ouvrez le terminal dans votre WebIDE et exécutez le script hello.py directement :

python3 hello.py

Vous verrez la sortie suivante, car les deux instructions print sont exécutées :

This code runs on import or direct execution.
This code runs ONLY when the script is executed directly.

Ceci démontre le comportement d'un script lorsqu'il est le programme principal en cours d'exécution. À l'étape suivante, nous verrons ce qui se passe lorsque nous l'importons comme un module.

Importer des Modules avec l'Instruction import

La manière la plus courante d'utiliser un module est de l'importer en utilisant l'instruction import. Cela rend tout le code du module disponible pour votre script actuel.

Dans l'explorateur de fichiers, vous trouverez un fichier vide nommé main.py. Ce sera notre script principal pour le reste du laboratoire.

Ouvrez main.py et ajoutez la ligne suivante pour importer le module hello :

import hello

print("The main.py script has finished.")

Enregistrez le fichier. Maintenant, exécutez main.py depuis le terminal :

python3 main.py

Observez attentivement la sortie :

This code runs on import or direct execution.
The main.py script has finished.

Remarquez que seule la première instruction print de hello.py a été exécutée. Le code à l'intérieur du bloc if __name__ == "__main__": a été ignoré. Cela est dû au fait que lorsque main.py importe hello, la variable __name__ dans le contexte de hello.py est définie sur "hello" (le nom du module), et non sur "__main__". Cette fonctionnalité est essentielle pour créer des modules réutilisables qui ne produisent pas d'effets secondaires indésirables lors de l'importation.

Maintenant, travaillons avec un module qui contient plus que de simples instructions d'impression. Ouvrez le fichier module_a.py. Il contient une variable, une fonction et une classe.

PI = 3.14159

def greet(name):
 print(f"Hello, {name} from module_a!")

class Calculator:
    def add(self, x, y):
        return x + y

Modifiez main.py pour importer module_a et utiliser ses membres. Pour accéder à un membre d'un module importé, vous utilisez la syntaxe nom_du_module.nom_du_membre.

Remplacez le contenu de main.py par ce qui suit :

import module_a

## Access the PI variable
print(f"The value of PI is {module_a.PI}")

## Call the greet function
module_a.greet("LabEx")

## Create an instance of the Calculator class and use its method
calc = module_a.Calculator()
result = calc.add(5, 3)
print(f"5 + 3 = {result}")

Enregistrez le fichier et exécutez-le :

python3 main.py

La sortie sera :

The value of PI is 3.14159
Hello, LabEx from module_a!
5 + 3 = 8

Ceci démontre comment l'instruction import charge un module entier, et comment vous accédez à son contenu en utilisant le nom du module comme préfixe.

Importer des Objets Spécifiques avec from...import

Parfois, vous n'avez besoin que de quelques éléments spécifiques d'un module. L'instruction from...import vous permet d'importer des fonctions, des classes ou des variables spécifiques directement dans l'espace de noms (namespace) de votre script actuel. Cela signifie que vous pouvez les utiliser sans le préfixe nom_du_module..

Modifions main.py pour utiliser cette méthode d'importation. Au lieu d'importer l'intégralité de module_a, nous importerons uniquement la variable PI et la fonction greet.

Mettez à jour main.py avec le code suivant :

from module_a import PI, greet

## Access PI and greet directly without the module prefix
print(f"The value of PI is {PI}")
greet("World")

Enregistrez le fichier et exécutez-le depuis le terminal :

python3 main.py

La sortie sera :

The value of PI is 3.14159
Hello, World from module_a!

Comme vous pouvez le constater, PI et greet sont utilisés directement. Cependant, si vous essayez d'accéder à quelque chose que vous n'avez pas importé, comme la classe Calculator, vous obtiendrez une erreur.

Essayez maintenant. Ajoutez les lignes suivantes à la fin de main.py :

calc = Calculator()
print(calc.add(10, 20))

Exécutez à nouveau le script :

python3 main.py

Cette fois, le script échouera avec une NameError (Erreur de Nom) :

The value of PI is 3.14159
Hello, World from module_a!
Traceback (most recent call last):
  File "/home/labex/project/main.py", line 7, in <module>
    calc = Calculator()
NameError: name 'Calculator' is not defined

Cette erreur confirme que seuls les objets spécifiés dans l'instruction from...import sont importés dans l'espace de noms actuel. Cette méthode peut rendre votre code plus lisible, mais augmente également le risque de conflits de noms si vous importez des objets portant le même nom à partir de modules différents.

Avant de passer à l'étape suivante, supprimez les deux lignes qui ont provoqué l'erreur de main.py.

Comprendre et Utiliser les Packages Python

À mesure que les projets grandissent, vous voudrez peut-être organiser les modules connexes dans une seule hiérarchie de répertoires. C'est l'utilité des packages. Un package est un répertoire qui contient un fichier spécial nommé __init__.py (qui peut être vide). La présence de ce fichier indique à Python de traiter le répertoire comme un package.

Créons un package pour contenir notre module_a.

Tout d'abord, créez un nouveau répertoire nommé my_package dans le répertoire ~/project. Vous pouvez le faire en faisant un clic droit dans l'explorateur de fichiers et en sélectionnant "Nouveau Dossier".

mkdir my_package

Ensuite, créez le fichier __init__.py requis à l'intérieur du nouveau répertoire my_package.

touch my_package/__init__.py

Maintenant, déplacez module_a.py dans le répertoire my_package. Vous pouvez faire glisser et déposer le fichier dans l'explorateur de fichiers.

mv module_a.py my_package/

La structure de votre projet devrait maintenant ressembler à ceci :

~/project/
├── main.py
├── hello.py
└── my_package/
    ├── __init__.py
    └── module_a.py

Avec cette structure de package en place, nous devons mettre à jour la manière dont nous importons module_a dans notre script main.py. Pour importer un module à partir d'un package, vous utilisez des noms de modules pointés, comme nom_du_package.nom_du_module.

Ouvrez main.py et modifiez-le pour importer la fonction greet depuis my_package.module_a :

from my_package.module_a import greet

greet("Package")

Enregistrez le fichier et exécutez-le :

python3 main.py

Vous devriez voir la sortie suivante :

Hello, Package from module_a!

Ceci montre comment importer un objet spécifique à partir d'un module à l'intérieur d'un package. Alternativement, vous pourriez importer le module lui-même :

## Alternative import style
import my_package.module_a

my_package.module_a.greet("Alternative")

Les packages sont un outil puissant pour organiser les grandes bases de code, telles que les bibliothèques et les frameworks, en une structure claire et maintenable.

Résumé

Dans ce laboratoire, vous avez appris les concepts essentiels de l'organisation du code en Python. Vous avez commencé par comprendre ce qu'est un module et l'objectif du bloc if __name__ == "__main__": pour créer du code réutilisable. Vous vous êtes ensuite exercé à importer des modules en utilisant la syntaxe import nom_du_module et à accéder à leurs membres avec la notation par point.

De plus, vous avez exploré l'instruction from...import pour importer des objets spécifiques d'un module directement dans l'espace de noms de votre script. Enfin, vous avez appris à structurer des modules connexes en un package en créant un répertoire avec un fichier __init__.py, et comment importer à partir de ce package. Ces compétences sont fondamentales pour écrire des applications Python propres, organisées et évolutives.