Introduction
Dans ce laboratoire, vous apprendrez les bases des modules Python. Les modules sont des fichiers Python contenant des définitions de fonctions, de classes et de variables qui peuvent être utilisées dans d'autres programmes Python. Ils aident à organiser le code en unités logiques et à améliorer la réutilisabilité.
À la fin de ce laboratoire, vous comprendrez comment créer vos propres modules, les importer de diverses manières et maîtriser les comportements importants de chargement des modules qui ont un impact sur votre code.
Création d'un module simple
Commençons notre exploration des modules Python en créant un module simple. En Python, un module est essentiellement un fichier avec une extension .py qui contient du code Python. Imaginez - le comme un conteneur dans lequel vous pouvez regrouper des fonctions, des classes et des variables liées. Cela rend votre code plus organisé et plus facile à gérer, surtout à mesure que vos projets augmentent en taille.
Tout d'abord, ouvrez le WebIDE. Une fois qu'il est ouvert, vous devrez créer un nouveau fichier. Pour ce faire, cliquez sur "File" dans la barre de menu, puis sélectionnez "New File". Nommez ce nouveau fichier
simplemod.pyet enregistrez - le dans le répertoire/home/labex/project. C'est dans ce répertoire que nous allons conserver tous les fichiers liés à cette expérience.Maintenant, ajoutons du code à notre fichier
simplemod.pynouvellement créé. Le code ci - dessous définit quelques éléments de base que vous trouverez souvent dans un module Python.
## simplemod.py
x = 42 ## Une variable globale
## Une fonction simple
def foo():
print('x is', x)
## Une classe simple
class Spam:
def yow(self):
print('Yow!')
## Une instruction de script
print('Loaded simplemod')
Dans ce code :
x = 42crée une variable globale nomméexet lui assigne la valeur42. Les variables globales peuvent être accédées depuis n'importe où dans le module.- La fonction
foo()est définie pour afficher la valeur de la variable globalex. Les fonctions sont des blocs de code réutilisables qui effectuent une tâche spécifique. - La classe
Spamest un modèle pour créer des objets. Elle a une méthode appeléeyow(), qui affiche simplement la chaîne de caractères 'Yow!'. Les méthodes sont des fonctions appartenant à une classe. - L'instruction
print('Loaded simplemod')est une instruction de script. Elle s'exécutera dès que le module sera chargé, ce qui nous aide à confirmer que le module a été chargé avec succès.
- Après avoir ajouté le code, enregistrez le fichier. Vous pouvez le faire en appuyant sur
Ctrl+Ssur votre clavier ou en sélectionnant "File" > "Save" dans le menu. Enregistrer le fichier garantit que toutes les modifications que vous avez apportées sont conservées.
Regardons de plus près ce que contient ce module :
- Une variable globale
xavec la valeur42. Cette variable peut être utilisée dans tout le module et même accédée depuis d'autres modules si elle est correctement importée. - Une fonction
foo()qui affiche la valeur dex. Les fonctions sont utiles pour effectuer des tâches répétitives sans avoir à écrire le même code plusieurs fois. - Une classe
Spamavec une méthodeyow(). Les classes et les méthodes sont des concepts fondamentaux en programmation orientée objet, qui vous permettent de créer des structures de données et des comportements complexes. - Une instruction
printqui s'exécute lorsque le module est chargé. Cette instruction sert d'indicateur visuel que le module a été chargé avec succès dans l'environnement Python.
L'instruction print en bas nous aidera à observer quand le module est chargé, ce qui est important pour le débogage et la compréhension du fonctionnement des modules en Python.
Importation et utilisation de modules
Maintenant que nous avons créé un module, il est temps de comprendre comment l'importer et utiliser ses composants. En Python, un module est un fichier contenant des définitions et des instructions Python. Lorsque vous importez un module, vous avez accès à toutes les fonctions, classes et variables définies à l'intérieur. Cela vous permet de réutiliser le code et d'organiser vos programmes plus efficacement.
Tout d'abord, nous devons ouvrir un nouveau terminal dans le WebIDE. Ce terminal servira de workspace où nous pouvons exécuter des commandes Python. Pour ouvrir un nouveau terminal, cliquez sur "Terminal" > "New Terminal".
Une fois le terminal ouvert, nous devons démarrer l'interpréteur Python. L'interpréteur Python est un programme qui lit et exécute le code Python. Pour le démarrer, tapez la commande suivante dans le terminal et appuyez sur Entrée :
python3
- Maintenant que l'interpréteur Python est en cours d'exécution, nous pouvons importer notre module. En Python, nous utilisons l'instruction
importpour inclure un module dans notre programme actuel. Tapez la commande suivante dans l'interpréteur Python :
>>> import simplemod
Loaded simplemod
Vous remarquerez que "Loaded simplemod" apparaît dans la sortie. C'est parce que l'instruction print dans notre module simplemod s'exécute lorsque le module est chargé. Lorsque Python importe un module, il exécute tout le code de niveau supérieur dans ce module, y compris les instructions print.
- Après avoir importé le module, nous pouvons accéder à ses composants en utilisant la notation pointée. La notation pointée est un moyen d'accéder aux attributs (variables et fonctions) d'un objet en Python. Dans ce cas, le module est un objet, et ses fonctions, variables et classes sont ses attributs. Voici quelques exemples de comment accéder à différents composants du module
simplemod:
>>> simplemod.x
42
>>> simplemod.foo()
x is 42
>>> spam_instance = simplemod.Spam()
>>> spam_instance.yow()
Yow!
Dans la première ligne, nous accédons à la variable x définie dans le module simplemod. Dans la deuxième ligne, nous appelons la fonction foo du module simplemod. Dans la troisième et la quatrième lignes, nous créons une instance de la classe Spam définie dans le module simplemod et appelons sa méthode yow.
- Parfois, vous pourriez rencontrer une erreur
ImportErrorlorsque vous essayez d'importer un module. Cette erreur se produit lorsque Python ne peut pas trouver le module que vous essayez d'importer. Pour savoir où Python cherche les modules, vous pouvez examiner la variablesys.path. La variablesys.pathest une liste de répertoires que Python recherche lorsqu'il cherche des modules. Tapez les commandes suivantes dans l'interpréteur Python :
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
Le premier élément de la liste (la chaîne vide) représente le répertoire de travail actuel. C'est là que Python cherche le fichier simplemod.py. Si votre module n'est pas dans l'un des répertoires répertoriés dans sys.path, Python ne pourra pas le trouver, et vous obtiendrez une erreur ImportError. Assurez - vous que votre fichier simplemod.py se trouve dans le répertoire de travail actuel ou dans l'un des autres répertoires de sys.path.
Comprendre le comportement de chargement des modules
En Python, la manière dont les modules sont chargés présente certaines caractéristiques intéressantes. Dans cette étape, nous allons explorer ces comportements pour comprendre comment Python gère le chargement des modules.
- Tout d'abord, voyons ce qui se passe lorsque nous essayons d'importer un module à nouveau au sein de la même session de l'interpréteur Python. Lorsque vous démarrez l'interpréteur Python, c'est comme ouvrir un espace de travail où vous pouvez exécuter du code Python. Une fois que vous avez importé un module, importer le même module à nouveau pourrait sembler recharger le module, mais ce n'est pas le cas.
>>> import simplemod
Remarquez que cette fois, vous ne voyez pas le message "Loaded simplemod" s'afficher. C'est parce que Python ne charge un module qu'une seule fois par session de l'interpréteur. Les instructions import suivantes ne rechargent pas le module. Python se souvient qu'il a déjà chargé le module, donc il ne refait pas le processus de chargement.
- Après avoir importé un module, vous pouvez modifier les variables à l'intérieur. Un module en Python est comme un conteneur qui contient des variables, des fonctions et des classes. Une fois que vous avez importé un module, vous pouvez accéder et modifier ses variables tout comme vous le feriez avec n'importe quel autre objet Python.
>>> simplemod.x
42
>>> simplemod.x = 13
>>> simplemod.x
13
>>> simplemod.foo()
x is 13
Ici, nous vérifions d'abord la valeur de la variable x dans le module simplemod, qui est initialement 42. Ensuite, nous changeons sa valeur en 13 et vérifions que le changement a été effectué. Lorsque nous appelons la fonction foo dans le module, elle reflète la nouvelle valeur de x.
- Importer le module à nouveau ne réinitialise pas les modifications que nous avons apportées à ses variables. Même si nous essayons d'importer le module une fois de plus, Python ne le recharge pas, donc les modifications que nous avons apportées à ses variables persistent.
>>> import simplemod
>>> simplemod.x
13
- Si vous souhaitez forcer le rechargement d'un module, vous devez utiliser la fonction
importlib.reload(). Parfois, vous avez peut - être apporté des modifications au code du module et vous souhaitez voir ces modifications prendre effet immédiatement. La fonctionimportlib.reload()vous permet de faire cela.
>>> import importlib
>>> importlib.reload(simplemod)
Loaded simplemod
<module 'simplemod' from 'simplemod.py'>
>>> simplemod.x
42
>>> simplemod.foo()
x is 42
Le module a été rechargé, et la valeur de x a été réinitialisée à 42. Cela montre que le module a été chargé à nouveau à partir de son code source, et toutes les variables ont été initialisées comme à l'origine.
- Python garde une trace de tous les modules chargés dans le dictionnaire
sys.modules. Ce dictionnaire agit comme un registre où Python stocke des informations sur tous les modules qui ont été chargés au cours de la session actuelle de l'interpréteur.
>>> 'simplemod' in sys.modules
True
>>> sys.modules['simplemod']
<module 'simplemod' from 'simplemod.py'>
En vérifiant si le nom d'un module est dans le dictionnaire sys.modules, vous pouvez voir si le module a été chargé. Et en accédant au dictionnaire avec le nom du module comme clé, vous pouvez obtenir des informations sur le module.
- Vous pouvez supprimer un module de ce dictionnaire pour forcer Python à le recharger lors de la prochaine importation. Si vous supprimez un module du dictionnaire
sys.modules, Python oublie qu'il a déjà chargé le module. Donc, la prochaine fois que vous essayez de l'importer, Python le chargera à nouveau à partir de son code source.
>>> del sys.modules['simplemod']
>>> import simplemod
Loaded simplemod
>>> simplemod.x
42
Le module a été rechargé car il a été supprimé de sys.modules. C'est une autre façon de vous assurer que vous travaillez avec la dernière version du code d'un module.
Utilisation de la syntaxe from module import
En Python, il existe diverses manières d'importer des composants à partir de modules. L'une de ces manières est la syntaxe from module import, que nous allons explorer dans cette section.
Lorsque vous importez des composants à partir d'un module, il est souvent judicieux de commencer avec un environnement propre. Cela garantit qu'il n'y a pas de variables ou de paramètres laissés de côtés par des interactions précédentes qui pourraient interférer avec notre expérience actuelle.
- Redémarrez l'interpréteur Python pour obtenir un environnement propre :
>>> exit()
Cette commande quitte la session actuelle de l'interpréteur Python. Après avoir quitté, nous allons démarrer une nouvelle session pour garantir un environnement neuf.
python3
Cette commande bash démarre une nouvelle session de l'interpréteur Python 3. Maintenant que nous avons un environnement Python propre, nous pouvons commencer à importer des composants à partir d'un module.
- Importez des composants spécifiques d'un module en utilisant la syntaxe
from module import:
>>> from simplemod import foo
Loaded simplemod
>>> foo()
x is 42
Ici, nous utilisons l'instruction from simplemod import foo pour importer uniquement la fonction foo du module simplemod. Remarquez que même si nous n'avons demandé que la fonction foo, le module simplemod entier a été chargé. Cela est indiqué par le message "Loaded simplemod". La raison en est que Python doit charger tout le module pour accéder à la fonction foo.
- Lorsque vous utilisez
from module import, vous ne pouvez pas accéder au module lui - même :
>>> simplemod.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'simplemod' is not defined
Lorsque nous utilisons la syntaxe from module import, nous n'introduisons que les composants spécifiés directement dans notre espace de noms. Le nom du module lui - même n'est pas importé. Donc, lorsque nous essayons d'accéder à simplemod.foo(), Python ne reconnaît pas simplemod car il n'a pas été importé de cette manière.
- Vous pouvez importer plusieurs composants à la fois :
>>> from simplemod import x, foo
>>> x
42
>>> foo()
x is 42
La syntaxe from module import nous permet d'importer plusieurs composants d'un module en une seule instruction. Ici, nous importons à la fois la variable x et la fonction foo du module simplemod. Après l'importation, nous pouvons accéder directement à ces composants dans notre code.
- Lorsque vous importez une variable à partir d'un module, vous créez une nouvelle référence à l'objet, pas un lien vers la variable dans le module :
>>> x = 13 ## Change the local variable x
>>> x
13
>>> foo()
x is 42 ## The function still uses the module's x, not your local x
Lorsque nous importons une variable à partir d'un module, nous créons essentiellement une nouvelle référence au même objet dans notre espace de noms local. Donc, lorsque nous changeons la variable locale x en 13, cela n'affecte pas la variable x à l'intérieur du module simplemod. La fonction foo() fait toujours référence à la variable x du module, qui est 42. Comprendre ce concept est crucial pour éviter les confusions dans votre code.
Exploration des limitations du rechargement de modules
Le rechargement de modules est une fonctionnalité utile en Python, mais il présente certaines limitations, notamment lorsqu'il s'agit de classes. Dans cette section, nous allons explorer ces limitations étape par étape. Comprendre ces limitations est crucial pour les environnements de développement et de production.
- Redémarrez l'interpréteur Python :
Tout d'abord, nous devons redémarrer l'interpréteur Python. Cette étape est importante car elle garantit que nous commençons avec un environnement propre. Lorsque vous redémarrez l'interpréteur, tous les modules et variables précédemment importés sont effacés. Pour quitter l'interpréteur Python actuel, utilisez la commande
exit(). Ensuite, démarrez une nouvelle session de l'interpréteur Python en utilisant la commandepython3dans le terminal.
>>> exit()
python3
- Importez le module et créez une instance de la classe
Spam: Maintenant que nous avons une nouvelle session de l'interpréteur Python, nous allons importer le modulesimplemod. L'importation d'un module nous permet d'utiliser les classes, les fonctions et les variables définies dans ce module. Après avoir importé le module, nous allons créer une instance de la classeSpamet appeler sa méthodeyow(). Cela nous aidera à voir le comportement initial de la classe.
>>> import simplemod
Loaded simplemod
>>> s = simplemod.Spam()
>>> s.yow()
Yow!
- Modifions maintenant la classe
Spamdans notre module. Quittez l'interpréteur Python : Ensuite, nous allons apporter des modifications à la classeSpamdans le modulesimplemod. Avant de le faire, nous devons quitter l'interpréteur Python. Cela s'explique par le fait que nous voulons modifier le code source du module et voir ensuite comment ces modifications affectent le comportement de la classe.
>>> exit()
- Ouvrez le fichier
simplemod.pydans le WebIDE et modifiez la classeSpam: Ouvrez le fichiersimplemod.pydans le WebIDE. C'est là que se trouve le code source du modulesimplemod. Nous allons modifier la méthodeyow()de la classeSpampour qu'elle affiche un message différent. Ce changement nous aidera à observer comment le comportement de la classe change après le rechargement du module.
## simplemod.py
## ... (laisser le reste du fichier inchangé)
class Spam:
def yow(self):
print('More Yow!') ## Changé de 'Yow!'
- Enregistrez le fichier et revenez au terminal. Démarrez l'interpréteur Python et créez une nouvelle instance :
Après avoir apporté les modifications au fichier
simplemod.py, enregistrez - le. Ensuite, revenez au terminal et démarrez une nouvelle session de l'interpréteur Python. Importez à nouveau le modulesimplemodet créez une nouvelle instance de la classeSpam. Appelez la méthodeyow()de la nouvelle instance pour voir le comportement mis à jour.
python3
>>> import simplemod
Loaded simplemod
>>> t = simplemod.Spam()
>>> t.yow()
More Yow!
- Montrez maintenant ce qui se passe lors du rechargement :
Pour voir comment le rechargement de module fonctionne, nous allons utiliser la fonction
importlib.reload(). Cette fonction nous permet de recharger un module précédemment importé. Après avoir rechargé le module, nous verrons si les modifications que nous avons apportées à la classeSpamsont prises en compte.
>>> import importlib
>>> importlib.reload(simplemod)
Loaded simplemod
<module 'simplemod' from 'simplemod.py'>
- Quittez Python, modifiez à nouveau le fichier, puis testez les deux instances :
Quittez l'interpréteur Python une fois de plus. Ensuite, apportez une autre modification à la classe
Spamdans le fichiersimplemod.py. Après cela, nous allons tester à la fois l'ancienne et la nouvelle instance de la classeSpampour voir comment elles se comportent.
>>> exit()
- Mettez à jour le fichier
simplemod.py: Ouvrez à nouveau le fichiersimplemod.pyet modifiez la méthodeyow()de la classeSpampour qu'elle affiche un message différent. Ce changement nous aidera à mieux comprendre les limitations du rechargement de module.
## simplemod.py
## ... (laisser le reste du fichier inchangé)
class Spam:
def yow(self):
print('Even More Yow!') ## Changé à nouveau
- Enregistrez le fichier et revenez au terminal :
Enregistrez les modifications apportées au fichier
simplemod.pyet revenez au terminal. Démarrez une nouvelle session de l'interpréteur Python, importez le modulesimplemodet créez une nouvelle instance de la classeSpam. Appelez la méthodeyow()de la nouvelle instance pour voir le comportement mis à jour.
python3
>>> import simplemod
Loaded simplemod
>>> s = simplemod.Spam()
>>> s.yow()
Even More Yow!
>>> ## Quittez sans fermer Python, modifiez le fichier
- Sans fermer Python, ouvrez
simplemod.pydans le WebIDE et modifiez - le : Sans fermer l'interpréteur Python, ouvrez le fichiersimplemod.pydans le WebIDE et apportez une autre modification à la méthodeyow()de la classeSpam. Cela nous aidera à voir comment le comportement des instances existantes et nouvelles change après le rechargement du module.
## simplemod.py
## ... (laisser le reste du fichier inchangé)
class Spam:
def yow(self):
print('Super Yow!') ## Changé une fois de plus
- Enregistrez le fichier et revenez à l'interpréteur Python :
Enregistrez les modifications apportées au fichier
simplemod.pyet revenez à l'interpréteur Python. Rechargez le modulesimplemoden utilisant la fonctionimportlib.reload(). Ensuite, testez à la fois l'ancienne et la nouvelle instance de la classeSpampour voir comment elles se comportent.
>>> import importlib
>>> importlib.reload(simplemod)
Loaded simplemod
<module 'simplemod' from 'simplemod.py'>
>>> ## Essayez l'ancienne instance
>>> s.yow()
Even More Yow! ## Utilise toujours l'ancienne implémentation
>>> ## Créez une nouvelle instance
>>> t = simplemod.Spam()
>>> t.yow()
Super Yow! ## Utilise la nouvelle implémentation
Remarquez que l'ancienne instance s utilise toujours l'ancienne implémentation, tandis que la nouvelle instance t utilise la nouvelle implémentation. Cela se produit car le rechargement d'un module ne met pas à jour les instances existantes de classes. Lorsqu'une instance de classe est créée, elle stocke une référence à l'objet de classe à ce moment. Le rechargement du module crée un nouvel objet de classe, mais les instances existantes font toujours référence à l'ancien objet de classe.
- Vous pouvez également observer d'autres comportements inhabituels :
Nous pouvons observer davantage les limitations du rechargement de module en utilisant la fonction
isinstance(). Cette fonction vérifie si un objet est une instance d'une classe particulière. Après avoir rechargé le module, nous verrons que l'ancienne instancesn'est plus considérée comme une instance de la nouvelle classesimplemod.Spam, tandis que la nouvelle instancetl'est.
>>> isinstance(s, simplemod.Spam)
False
>>> isinstance(t, simplemod.Spam)
True
Cela indique qu'après le rechargement, simplemod.Spam fait référence à un objet de classe différent de celui utilisé pour créer s.
Ces limitations rendent le rechargement de module utile principalement pour le développement et le débogage, mais il n'est pas recommandé pour le code de production. Dans un environnement de production, il est important de s'assurer que toutes les instances d'une classe utilisent la même implémentation à jour. Le rechargement de module peut entraîner un comportement incohérent, qui peut être difficile à déboguer et à maintenir.
Résumé
Dans ce laboratoire, vous avez appris les bases de l'utilisation des modules en Python. Vous avez appris à créer un module Python sous forme de fichier .py contenant des variables, des fonctions et des classes, ainsi qu'à importer des modules à l'aide de l'instruction import. Vous savez également que Python charge les modules une seule fois par session d'interpréteur et que vous pouvez utiliser importlib.reload() pour forcer le rechargement.
De plus, vous avez exploré le dictionnaire sys.modules pour suivre les modules chargés, utilisé la syntaxe from module import pour importer des composants spécifiques et compris les limitations du rechargement de modules, notamment en ce qui concerne les classes. Ces concepts constituent la base pour organiser le code Python en composants réutilisables, ce qui est essentiel pour maintenir la structure du code et favoriser la réutilisabilité dans les applications plus importantes.