Von einer Datei zu einem Ordner voller Module
Eine einzelne Datei genügt nicht mehr, wenn ein Projekt wächst. Ein Paket ist ein Ordner mit Modulen, den Python als Einheit importieren kann. Markieren Sie den Ordner mit einer Datei namens __init__.py (sie darf leer sein), und jede .py-Datei darin wird zu einem Modul des Pakets, angesprochen mit Punkten: quant/pricing.py ist quant.pricing, und quant/data/loaders.py ist quant.data.loaders. Ordner in einem Paket sind Unterpakete und brauchen ein eigenes __init__.py.
# A small project on disk
#
# quant-tools/
# pyproject.toml
# README.md
# quant/
# __init__.py
# pricing.py
# data/
# __init__.py
# loaders.py
# tests/
# test_pricing.py
# quant/pricing.py
def mid(bid, ask):
return (bid + ask) / 2
# anywhere else in the project
from quant.pricing import mid
import quant.data.loaders
print(mid(184.0, 185.0)) # 184.5Eine Struktur, die mitwächst
Halten Sie den importierbaren Code in einem Paketordner mit dem Projektnamen und alles andere daneben, nicht darin: Tests in tests/, eine README.md, die das Projekt erklärt, eine pyproject.toml, die es benennt und seine Abhängigkeiten listet, und Daten oder Notebooks in eigenen Ordnern. Testdateien heißen test_*.py, damit Werkzeuge wie pytest sie finden. Kleine, fokussierte Module mit klaren Namen (pricing.py, loaders.py) sind leichter zu testen und wiederzuverwenden als eine lange utils.py.
# pyproject.toml (names the project and its dependencies)
#
# [project]
# name = "quant-tools"
# version = "0.1.0"
# requires-python = ">=3.11"
# dependencies = ["numpy"]
# tests/test_pricing.py: found automatically because of the name
from quant.pricing import mid
def test_mid():
assert mid(184.0, 185.0) == 184.5Importieren innerhalb eines Pakets
Innerhalb des Pakets können Sie mit vollem Pfad von oben importieren (from quant.pricing import mid, absoluter Import) oder relativ zum aktuellen Modul (from .pricing import mid, ein Punkt für dasselbe Paket, zwei für das übergeordnete, relativer Import). Absolute Importe sind meist klarer. __init__.py läuft beim ersten Import des Pakets und kann daher die nötigen Namen weiterreichen (from .pricing import mid), sodass import quant; quant.mid(...) funktioniert. Starten Sie Paketcode mit python -m quant.data.loaders, nicht mit python quant/data/loaders.py, damit die Namen mit Punkten aufgelöst werden.
# quant/__init__.py: runs on the first "import quant"
from .pricing import mid # relative: same package
__all__ = ["mid"] # what "from quant import *" would give
# quant/data/loaders.py
from quant.pricing import mid # absolute: always starts at the top
from .. import pricing # relative: two dots = the parent package
# In a terminal, from the project folder:
# python -m quant.data.loaders (runs the module as part of the package)
# pytest -q (finds tests/test_*.py)# A file path and its module name are two spellings of one thing
path = "quant/data/loaders.py"
name = path[:-3].replace("/", ".")
print(name) # quant.data.loaders
print(name.split(".")[0]) # quant (the top-level package)
# __init__.py stands for its folder
print("quant/__init__.py"[:-3].replace("/", ".")) # quant.__init__ -> the package is "quant"__init__.py importieren (ein „Namespace-Paket“), doch Werkzeuge, Test-Runner und Installer verhalten sich damit uneinheitlich, und Importe, die bei Ihnen liefen, scheitern anderswo. Geben Sie jedem Paketordner ein __init__.py. Das Lab verlangt, Ordner zu finden, die Code enthalten, aber keins haben.- Ein Paket ist ein Ordner mit
__init__.py;quant/data/loaders.pyist das Modulquant.data.loaders. - Code im Paket; Tests, README,
pyproject.tomlund Daten daneben. - Bevorzugen Sie absolute Importe; starten Sie Paketcode mit
python -m package.module.
Als Nächstes: virtuelle Umgebungen und pip, damit jedes Projekt genau die Bibliotheken bekommt, die es braucht.
Lab: Was bewertet wird
- Mit
module_nameeinen Dateipfad in einen Modulnamen verwandeln25 Pkt. - Mit
find_modulesdie importierbaren Module eines Projekts auflisten25 Pkt. - Mit
missing_initOrdner ohne __init__.py erkennen25 Pkt. - Mit
import_linedie Import-Anweisung für ein Modul schreiben25 Pkt.