Introduction
Cette section présente le concept de modules et la manipulation de fonctions qui s'étendent sur plusieurs fichiers.
This tutorial is from open-source community. Access the source code
💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici
Cette section présente le concept de modules et la manipulation de fonctions qui s'étendent sur plusieurs fichiers.
Tout fichier source Python est un module.
## foo.py
def grok(a):
...
def spam(b):
...
L'instruction import
charge et exécute un module.
## program.py
import foo
a = foo.grok(2)
b = foo.spam('Hello')
...
Un module est une collection de valeurs nommées et est parfois appelé un espace de noms. Les noms sont toutes les variables globales et les fonctions définies dans le fichier source. Après l'importation, le nom du module est utilisé comme préfixe. D'où l'espace de noms.
import foo
a = foo.grok(2)
b = foo.spam('Hello')
...
Le nom du module est directement lié au nom de fichier (foo -> foo.py).
Tout ce qui est défini dans l'espace de portée globale est ce qui remplit l'espace de noms du module. Considérez deux modules qui définissent la même variable x
.
## foo.py
x = 42
def grok(a):
...
## bar.py
x = 37
def spam(a):
...
Dans ce cas, les définitions de x
se réfèrent à des variables différentes. L'une est foo.x
et l'autre est bar.x
. Différents modules peuvent utiliser les mêmes noms et ces noms ne se conflitent pas les uns avec les autres.
Les modules sont isolés.
Les modules forment un environnement entourant tout le code défini à l'intérieur.
## foo.py
x = 42
def grok(a):
print(x)
Les variables globales sont toujours liées au module entourant (même fichier). Chaque fichier source est son propre petit univers.
Lorsque l'on importe un module, toutes les instructions du module s'exécutent les unes après les autres jusqu'à la fin du fichier. Le contenu de l'espace de noms du module est tous les noms globaux qui sont encore définis à la fin du processus d'exécution. Si vous avez des instructions de script qui effectuent des tâches dans l'espace de portée globale (affichage, création de fichiers, etc.), vous les verrez s'exécuter lors de l'importation.
import as
Vous pouvez modifier le nom d'un module lors de son importation :
import math as m
def rectangular(r, theta):
x = r * m.cos(theta)
y = r * m.sin(theta)
return x, y
Ça fonctionne de la même manière qu'un import normal. Il ne fait que renommer le module dans ce fichier-là.
from
)Cela permet de sélectionner des symboles d'un module et de les rendre disponibles localement.
from math import sin, cos
def rectangular(r, theta):
x = r * cos(theta)
y = r * sin(theta)
return x, y
Cela permet d'utiliser des parties d'un module sans avoir à taper le préfixe du module. C'est pratique pour les noms utilisés fréquemment.
Les variations de l'importation ne changent pas la manière dont les modules fonctionnent.
import math
## vs
import math as m
## vs
from math import cos, sin
...
Plus précisément, import
exécute toujours tout le fichier et les modules restent des environnements isolés.
L'instruction import module as
ne fait que changer le nom localement. L'instruction from math import cos, sin
charge toujours le module mathématique en arrière-plan. Elle ne fait que copier les noms cos
et sin
du module dans l'espace local une fois qu'elle est terminée.
Chaque module ne se charge et n'est exécuté qu'une seule fois. Remarque : Les importations répétées ne renvoient simplement qu'une référence au module chargé précédemment.
sys.modules
est un dictionnaire de tous les modules chargés.
>>> import sys
>>> sys.modules.keys()
['copy_reg', '__main__','site', '__builtin__', 'encodings', 'encodings.encodings', 'posixpath',...]
>>>
Attention : Une erreur fréquente se produit si vous répétez une instruction import
après avoir modifié le code source d'un module. En raison du cache des modules sys.modules
, les importations répétées renvoient toujours le module chargé précédemment - même si un changement a été effectué. Le moyen le plus sûr de charger le code modifié dans Python est d'arrêter et de redémarrer l'interpréteur.
Python consulte une liste de chemins (sys.path
) lorsqu'il recherche des modules.
>>> import sys
>>> sys.path
[
'',
'/usr/local/lib/python36/python36.zip',
'/usr/local/lib/python36',
...
]
Le répertoire de travail actuel est généralement le premier.
Comme indiqué, sys.path
contient les chemins de recherche. Vous pouvez l'ajuster manuellement si nécessaire.
import sys
sys.path.append('/project/foo/pyfiles')
Les chemins peuvent également être ajoutés via des variables d'environnement.
% env PYTHONPATH=/project/foo/pyfiles python3
Python 3.6.0 (default, Feb 3 2017, 05:53:21)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)]
>>> import sys
>>> sys.path
['','/project/foo/pyfiles',...]
En règle générale, il n'est pas nécessaire d'ajuster manuellement le chemin de recherche des modules. Cependant, cela peut arriver si vous essayez d'importer du code Python situé dans un emplacement inhabituel ou difficilement accessible depuis le répertoire de travail actuel.
Pour cet exercice sur les modules, il est crucial de vous assurer que vous exécutez Python dans un environnement approprié. Les modules posent souvent des problèmes aux nouveaux programmeurs liés au répertoire de travail actuel ou aux paramètres de chemin de Python. Pour ce cours, il est supposé que vous écrivez tout votre code dans le répertoire ~/project
. Pour obtenir les meilleurs résultats, vous devriez vous assurer également d'être dans ce répertoire lorsque vous lancez l'interpréteur. Sinon, vous devez vous assurer que ~/project
est ajouté à sys.path
.
Dans la section 3, nous avons créé une fonction générale parse_csv()
pour analyser le contenu de fichiers de données au format CSV.
Maintenant, nous allons voir comment utiliser cette fonction dans d'autres programmes. Commencez par ouvrir une nouvelle fenêtre de terminal. Naviguez vers le dossier où se trouvent tous vos fichiers. Nous allons les importer.
Démarrez le mode interactif de Python.
$ python3
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
Une fois que vous avez fait cela, essayez d'importer certains des programmes que vous avez précédemment écrits. Vous devriez voir leur sortie exactement comme avant. Pour souligner, importer un module exécute son code.
>>> import bounce
... observez la sortie...
>>> import mortgage
... observez la sortie...
>>> import report
... observez la sortie...
>>>
Si rien de cela ne fonctionne, vous êtes probablement exécutant Python dans le mauvais répertoire. Maintenant, essayez d'importer votre module fileparse
et d'obtenir de l'aide sur celui-ci.
>>> import fileparse
>>> help(fileparse)
... regardez la sortie...
>>> dir(fileparse)
... regardez la sortie...
>>>
Essayez d'utiliser le module pour lire certaines données :
>>> portfolio = fileparse.parse_csv('/home/labex/project/portfolio.csv',select=['name','shares','price'], types=[str,int,float])
>>> portfolio
... regardez la sortie...
>>> pricelist = fileparse.parse_csv('/home/labex/project/prices.csv',types=[str,float], has_headers=False)
>>> pricelist
... regardez la sortie...
>>> prices = dict(pricelist)
>>> prices
... regardez la sortie...
>>> prices['IBM']
106.28
>>>
Essayez d'importer une fonction pour ne pas avoir besoin d'inclure le nom du module :
>>> from fileparse import parse_csv
>>> portfolio = parse_csv('/home/labex/project/portfolio.csv', select=['name','shares','price'], types=[str,int,float])
>>> portfolio
... regardez la sortie...
>>>
Dans la section 2, vous avez écrit un programme report.py
qui produisait un rapport sur les actions comme ceci :
Nom Actions Prix Changement
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84
Prenez ce programme et modifiez-le de sorte que tout le traitement des fichiers d'entrée soit effectué à l'aide de fonctions dans votre module fileparse
. Pour ce faire, importez fileparse
en tant que module et modifiez les fonctions read_portfolio()
et read_prices()
pour utiliser la fonction parse_csv()
.
Utilisez l'exemple interactif au début de cet exercice comme guide. Ensuite, vous devriez obtenir exactement la même sortie qu'avant.
Dans la section 1, vous avez écrit un programme pcost.py
qui lisait un portefeuille et calculait son coût.
>>> import pcost
>>> pcost.portfolio_cost('/home/labex/project/portfolio.csv')
44671.15
>>>
Modifiez le fichier pcost.py
de sorte qu'il utilise la fonction report.read_portfolio()
.
Lorsque vous avez terminé cet exercice, vous devriez avoir trois programmes. fileparse.py
qui contient une fonction générale parse_csv()
. report.py
qui produit un bel état, mais contient également les fonctions read_portfolio()
et read_prices()
. Et enfin, pcost.py
qui calcule le coût du portefeuille, mais utilise la fonction read_portfolio()
écrite pour le programme report.py
.
Félicitations ! Vous avez terminé le laboratoire sur les modules. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.