Einführung
Wenn Sie ein größeres Programm schreiben, möchten Sie es nicht wirklich als eine große Sammlung von eigenständigen Dateien auf der obersten Ebene organisieren. Dieser Abschnitt stellt das Konzept eines Pakets vor.
This tutorial is from open-source community. Access the source code
💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken
Wenn Sie ein größeres Programm schreiben, möchten Sie es nicht wirklich als eine große Sammlung von eigenständigen Dateien auf der obersten Ebene organisieren. Dieser Abschnitt stellt das Konzept eines Pakets vor.
Jede Python-Quelldatei ist ein Modul.
## foo.py
def grok(a):
...
def spam(b):
...
Eine import
-Anweisung lädt und führt ein Modul aus.
## program.py
import foo
a = foo.grok(2)
b = foo.spam('Hello')
...
Für größere Code-Sammlungen ist es üblich, Module in ein Paket zu organisieren.
## Von diesem
pcost.py
report.py
fileparse.py
## Zu diesem
porty/
__init__.py
pcost.py
report.py
fileparse.py
Wählen Sie einen Namen und erstellen Sie ein oberstes Verzeichnis. porty
im obigen Beispiel (klarerweise ist das Wählen dieses Namens der wichtigste erste Schritt).
Fügen Sie eine __init__.py
-Datei in das Verzeichnis hinzu. Sie kann leer sein.
Legen Sie Ihre Quelltexte in das Verzeichnis ab.
Ein Paket dient als Namensraum für Imports.
Dies bedeutet, dass es jetzt Mehr-Ebene-Imports gibt.
import porty.report
port = porty.report.read_portfolio('portfolio.csv')
Es gibt auch andere Variationen von Importanweisungen.
from porty import report
port = report.read_portfolio('portfolio.csv')
from porty.report import read_portfolio
port = read_portfolio('portfolio.csv')
Es gibt zwei Hauptprobleme mit diesem Ansatz.
Also, im Grunde alles bricht. Aber abgesehen davon funktioniert es.
Imports zwischen Dateien im selben Paket müssen jetzt den Paketnamen im Import enthalten. Denken Sie sich die Struktur ein.
porty/
__init__.py
pcost.py
report.py
fileparse.py
Verändertes Importbeispiel.
from porty import fileparse
def read_portfolio(filename):
return fileparse.parse_csv(...)
Alle Imports sind absolut, nicht relativ.
import fileparse ## Bricht. fileparse nicht gefunden
...
Anstatt direkt den Paketnamen zu verwenden, können Sie .
verwenden, um auf das aktuelle Paket zu verweisen.
from. import fileparse
def read_portfolio(filename):
return fileparse.parse_csv(...)
Syntax:
from. import modname
Dies macht es einfach, das Paket umzubenennen.
Das Ausführen eines Paket-Untermoduls als Hauptskript bricht.
$ python porty/pcost.py ## Bricht
...
Grund: Sie führen Python auf einer einzelnen Datei aus und Python erkennt die restliche Paketstruktur nicht richtig (sys.path
ist falsch).
Alle Imports brechen. Um das zu beheben, müssen Sie Ihr Programm auf eine andere Weise ausführen, indem Sie die Option -m
verwenden.
$ python -m porty.pcost ## Funktioniert
...
__init__.py
-DateienDer primäre Zweck dieser Dateien besteht darin, Module zusammenzusetzen.
Beispiel: Zusammenführen von Funktionen
## porty/__init__.py
from.pcost import portfolio_cost
from.report import portfolio_report
Dadurch erscheinen die Namen auf der Hauptebene, wenn importiert wird.
from porty import portfolio_cost
portfolio_cost('portfolio.csv')
Anstatt die mehrstufigen Imports zu verwenden.
from porty import pcost
pcost.portfolio_cost('portfolio.csv')
Wie erwähnt, müssen Sie jetzt -m package.module
verwenden, um Skripte innerhalb Ihres Pakets auszuführen.
$ python3 -m porty.pcost portfolio.csv
Es gibt eine weitere Möglichkeit: Schreiben Sie ein neues Hauptskript.
#!/usr/bin/env python3
## pcost.py
import porty.pcost
import sys
porty.pcost.main(sys.argv)
Dieses Skript befindet sich außerhalb des Pakets. Beispielsweise betrachten Sie die Verzeichnisstruktur:
pcost.py ## Hauptskript
porty/ ## Paketverzeichnis
__init__.py
pcost.py
...
Die Codeorganisation und die Dateistruktur sind entscheidend für die Wartbarkeit einer Anwendung.
Es gibt keine "eines-fits-all"-Methode für Python. Ein Struktur, die jedoch für viele Probleme funktioniert, sieht so aus.
porty-app/
README.txt
script.py ## SKRIPT
porty/
## BIBLIOTHEKSCODE
__init__.py
pcost.py
report.py
fileparse.py
Das oberste Level porty-app
ist ein Container für alles andere - Dokumentation, oberste Level Skripte, Beispiele usw.
Wiederholen Sie, dass die obersten Level Skripte (falls vorhanden) außerhalb des Code-Pakets existieren müssen. Ein Level höher.
#!/usr/bin/env python3
## porty-app/script.py
import sys
import porty
porty.report.main(sys.argv)
Zu diesem Zeitpunkt haben Sie ein Verzeichnis mit mehreren Programmen:
pcost.py ## berechnet die Portfolio-Kosten
report.py ## Erstellt einen Bericht
ticker.py ## Erzeugt einen Echtzeit-Aktien-Ticker
Es gibt eine Vielzahl von unterstützenden Modulen mit anderen Funktionen:
stock.py ## Stock-Klasse
portfolio.py ## Portfolio-Klasse
fileparse.py ## CSV-Parsing
tableformat.py ## Formatierte Tabellen
follow.py ## Folgt einer Log-Datei
typedproperty.py ## Typisierte Klassen-Eigenschaften
In dieser Übung werden wir den Code aufräumen und in ein gemeinsames Paket einfügen.
Erstellen Sie ein Verzeichnis namens porty/
und legen Sie alle obigen Python-Dateien darin ab. Erstellen Sie zusätzlich eine leere __init__.py
-Datei und legen Sie sie im Verzeichnis ab. Sie sollten ein Verzeichnis mit Dateien wie dieses haben:
porty/
__init__.py
fileparse.py
follow.py
pcost.py
portfolio.py
report.py
stock.py
tableformat.py
ticker.py
typedproperty.py
Löschen Sie die Datei __pycache__
, die sich in Ihrem Verzeichnis befindet. Dies enthält zuvor kompilierte Python-Module. Wir möchten von vorne beginnen.
Versuchen Sie, einige der Paketmodule zu importieren:
>>> import porty.report
>>> import porty.pcost
>>> import porty.ticker
Wenn diese Imports fehlschlagen, gehen Sie in die entsprechende Datei und ändern Sie die Modulimporte, um einen paketrelativen Import zu verwenden. Beispielsweise könnte ein Statement wie import fileparse
wie folgt geändert werden:
## report.py
from. import fileparse
...
Wenn Sie ein Statement wie from fileparse import parse_csv
haben, ändern Sie den Code wie folgt:
## report.py
from.fileparse import parse_csv
...
Das Einbringen Ihres gesamten Codes in ein "Paket" reicht für eine Anwendung oft nicht aus. Manchmal gibt es unterstützende Dateien, Dokumentation, Skripte und andere Dinge. Diese Dateien müssen außerhalb des oben erstellten porty/
-Verzeichnisses existieren.
Erstellen Sie ein neues Verzeichnis namens porty-app
. Verschieben Sie das in Übung 9.1 erstellte porty
-Verzeichnis in dieses Verzeichnis. Kopieren Sie die Testdateien portfolio.csv
und prices.csv
in dieses Verzeichnis. Erstellen Sie zusätzlich eine README.txt
-Datei mit Informationen über sich selbst. Ihr Code sollte jetzt wie folgt organisiert sein:
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
Um Ihren Code auszuführen, müssen Sie sicherstellen, dass Sie im obersten Level-Verzeichnis porty-app/
arbeiten. Beispielsweise von der Kommandozeile:
$ cd porty-app
$ python3
>>> import porty.report
>>>
Versuchen Sie, einige Ihrer vorherigen Skripte als Hauptprogramm auszuführen:
$ 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
$
Das Verwenden des Befehls python -m
ist oft etwas ungewöhnlich. Möglicherweise möchten Sie ein oberstes Ebene Skript schreiben, das einfach mit den Besonderheiten von Paketen umgeht. Erstellen Sie ein Skript print-report.py
, das den obigen Bericht erzeugt:
#!/usr/bin/env python3
## print-report.py
import sys
from porty.report import main
main(sys.argv)
Legen Sie dieses Skript im obersten Level-Verzeichnis porty-app/
ab. Stellen Sie sicher, dass Sie es an diesem Ort ausführen können:
$ 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
$
Ihr endgültiger Code sollte jetzt ungefähr so strukturiert sein:
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
Herzlichen Glückwunsch! Sie haben das Lab zu Paketen abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.