Introduction
Si vous écrivez un programme plus important, vous ne voulez pas vraiment l'organiser comme une grande collection de fichiers indépendants au niveau supérieur. Cette section présente le concept d'un package.
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
Si vous écrivez un programme plus important, vous ne voulez pas vraiment l'organiser comme une grande collection de fichiers indépendants au niveau supérieur. Cette section présente le concept d'un package.
Tout fichier source Python est un module.
## foo.py
def grok(a):
...
def spam(b):
...
Une instruction import
charge et exécute un module.
## program.py
import foo
a = foo.grok(2)
b = foo.spam('Hello')
...
Pour de plus grandes collections de code, il est courant d'organiser les modules en un package.
## De cela
pcost.py
report.py
fileparse.py
## A cela
porty/
__init__.py
pcost.py
report.py
fileparse.py
Vous choisissez un nom et créez un répertoire de niveau supérieur. porty
dans l'exemple ci-dessus (choisir ce nom est clairement la première étape la plus importante).
Ajoutez un fichier __init__.py
au répertoire. Il peut être vide.
Placez vos fichiers sources dans le répertoire.
Un package sert de nommage pour les importations.
Cela signifie qu'il existe désormais des importations multi-niveaux.
import porty.report
port = porty.report.read_portfolio('portfolio.csv')
Il existe d'autres variantes d'instructions d'importation.
from porty import report
port = report.read_portfolio('portfolio.csv')
from porty.report import read_portfolio
port = read_portfolio('portfolio.csv')
Il y a deux principaux problèmes avec cette approche.
Donc, fondamentalement, tout ne fonctionne plus. Mais, hormis ça, ça marche.
Les importations entre fichiers dans le même package doivent désormais inclure le nom du package dans l'import. Rappelez-vous la structure.
porty/
__init__.py
pcost.py
report.py
fileparse.py
Exemple d'import modifié.
from porty import fileparse
def read_portfolio(filename):
return fileparse.parse_csv(...)
Toutes les importations sont absolues, pas relatives.
import fileparse ## NE FONCTIONNE PAS. fileparse non trouvé
...
Au lieu d'utiliser directement le nom du package, vous pouvez utiliser .
pour vous référer au package actuel.
from. import fileparse
def read_portfolio(filename):
return fileparse.parse_csv(...)
Syntaxe :
from. import modname
Cela facilite la renommation du package.
Exécuter un sous-module de package en tant que script principal ne fonctionne pas.
$ python porty/pcost.py ## NE FONCTIONNE PAS
...
Raison : Vous exécutez Python sur un seul fichier et Python ne voit pas correctement le reste de la structure du package (sys.path
est incorrect).
Toutes les importations ne fonctionnent pas. Pour résoudre ce problème, vous devez exécuter votre programme d'une manière différente, en utilisant l'option -m
.
$ python -m porty.pcost ## FONCTIONNE
...
__init__.py
Le principal but de ces fichiers est de rassembler les modules.
Exemple : consolidation de fonctions
## porty/__init__.py
from.pcost import portfolio_cost
from.report import portfolio_report
Cela permet d'avoir les noms disponibles au niveau supérieur lors de l'importation.
from porty import portfolio_cost
portfolio_cost('portfolio.csv')
Plutôt que d'utiliser des importations multi-niveaux.
from porty import pcost
pcost.portfolio_cost('portfolio.csv')
Comme indiqué, vous devez désormais utiliser -m package.module
pour exécuter les scripts dans votre package.
$ python3 -m porty.pcost portfolio.csv
Il existe une autre alternative : écrire un nouveau script de niveau supérieur.
#!/usr/bin/env python3
## pcost.py
import porty.pcost
import sys
porty.pcost.main(sys.argv)
Ce script se trouve en dehors du package. Par exemple, en examinant la structure de répertoire :
pcost.py ## script de niveau supérieur
porty/ ## répertoire du package
__init__.py
pcost.py
...
L'organisation du code et la structure des fichiers sont clés pour la maintenabilité d'une application.
Il n'y a pas d'approche "unique" pour Python. Cependant, une structure qui fonctionne pour de nombreux problèmes est la suivante.
porty-app/
README.txt
script.py ## SCRIPT
porty/
## CODE DE BIBLIOTHÈQUE
__init__.py
pcost.py
report.py
fileparse.py
Le niveau supérieur porty-app
est un conteneur pour tout le reste - la documentation, les scripts de niveau supérieur, les exemples, etc.
Encore une fois, les scripts de niveau supérieur (s'il y en a) doivent exister en dehors du package de code. Un niveau au-dessus.
#!/usr/bin/env python3
## porty-app/script.py
import sys
import porty
porty.report.main(sys.argv)
À ce stade, vous avez un répertoire avec plusieurs programmes :
pcost.py ## calcule le coût d'un portefeuille
report.py ## Génère un rapport
ticker.py ## Génère un indice boursier en temps réel
Il existe une variété de modules d'assistance avec d'autres fonctionnalités :
stock.py ## Classe Stock
portfolio.py ## Classe Portfolio
fileparse.py ## Analyse CSV
tableformat.py ## Tableaux formatés
follow.py ## Suivre un fichier de journal
typedproperty.py ## Propriétés de classe typées
Dans cet exercice, nous allons nettoyer le code et le placer dans un package commun.
Créez un répertoire appelé porty/
et placez tous les fichiers Python ci-dessus à l'intérieur. Créez également un fichier __init__.py
vide et placez-le dans le répertoire. Vous devriez avoir un répertoire de fichiers comme ceci :
porty/
__init__.py
fileparse.py
follow.py
pcost.py
portfolio.py
report.py
stock.py
tableformat.py
ticker.py
typedproperty.py
Supprimez le fichier __pycache__
qui se trouve dans votre répertoire. Celui-ci contient des modules Python pré-compilés antérieurement. Nous voulons commencer avec un état vierge.
Essayez d'importer certains des modules du package :
>>> import porty.report
>>> import porty.pcost
>>> import porty.ticker
Si ces importations échouent, accédez au fichier approprié et corrigez les importations de module pour inclure une importation relative au package. Par exemple, une instruction telle que import fileparse
pourrait devenir la suivante :
## report.py
from. import fileparse
...
Si vous avez une instruction telle que from fileparse import parse_csv
, changez le code en :
## report.py
from.fileparse import parse_csv
...
Placer tout votre code dans un "package" n'est souvent pas suffisant pour une application. Parfois, il y a des fichiers d'assistance, de la documentation, des scripts et autres éléments. Ces fichiers doivent exister EN DEHORS du répertoire porty/
que vous avez créé ci-dessus.
Créez un nouveau répertoire appelé porty-app
. Déplacez le répertoire porty
que vous avez créé dans l'Exercice 9.1 dans ce répertoire. Copiez les fichiers de test portfolio.csv
et prices.csv
dans ce répertoire. Créez également un fichier README.txt
avec quelques informations sur vous-même. Votre code devrait maintenant être organisé comme suit :
porty-app/
portfolio.csv
prices.csv
README.txt
porty/
__init__.py
fileparse.py
follow.py
pcost.py
portfolio.py
report.py
stock.py
tableformat.py
ticker.py
typedproperty.py
Pour exécuter votre code, vous devez vous assurer d'être dans le répertoire porty-app/
de niveau supérieur. Par exemple, à partir du terminal :
$ cd porty-app
$ python3
>>> import porty.report
>>>
Essayez d'exécuter certains de vos scripts antérieurs en tant que programme principal :
$ cd porty-app
$ python3 -m porty.report portfolio.csv prices.csv txt
Name Shares Price Change
---------- ---------- ---------- ----------
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
$
Utiliser la commande python -m
est souvent un peu étrange. Vous pouvez vouloir écrire un script de niveau supérieur qui traite simplement les particularités des packages. Créez un script print-report.py
qui produit le rapport ci-dessus :
#!/usr/bin/env python3
## print-report.py
import sys
from porty.report import main
main(sys.argv)
Placez ce script dans le répertoire porty-app/
de niveau supérieur. Assurez-vous de pouvoir l'exécuter à cet emplacement :
$ cd porty-app
$ python3 print-report.py portfolio.csv prices.csv txt
Name Shares Price Change
---------- ---------- ---------- ----------
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
$
Votre code final devrait maintenant être structuré comme ceci :
porty-app/
portfolio.csv
prices.csv
print-report.py
README.txt
porty/
__init__.py
fileparse.py
follow.py
pcost.py
portfolio.py
report.py
stock.py
tableformat.py
ticker.py
typedproperty.py
Félicitations ! Vous avez terminé le laboratoire sur les packages. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.