Achtergrond: Packages zijn in Python ontstaan om grote codebases te structureren en om hergebruik van code mogelijk te maken. Ze stellen je in staat om een project op te splitsen in logische modules en vergemakkelijken het onderhoud en de import van benodigde functionaliteit.
Probleem: Een onjuiste interpretatie van de structuur van packages leidt tot importfouten, naamsconflicten en uitvoeringsfouten van scripts. Het is belangrijk om het verschil tussen packages en modules te begrijpen, evenals de regels voor relatieve en absolute imports.
Oplossing:
Een package is elke directory met een bestand __init__.py (leeg of met initialisatiecode). Packages kunnen andere packages en modules bevatten. Voorbeeldstructuur:
project/
├── mypackage/
│ ├── __init__.py
│ ├── mod1.py
│ └── subpackage/
│ ├── __init__.py
│ └── mod2.py
└── script.py
Voor importeren gebruiken we een relatieve (from .subpackage import mod2) of absolute pad (from mypackage.subpackage import mod2). Absolute imports hebben de voorkeur voor grotere projecten.
Belangrijke kenmerken:
__init__.pyMoet init.py verplicht aanwezig zijn in elke map die we als package willen maken?
Ja, voor Python versies onder 3.3; in de moderne versies van Python (3.3+) zijn er "impliciete" namespace-packages, maar voor volledige compatibiliteit wordt het bestand toch aangeraden.
Wat gebeurt er als je een package importeert in plaats van een module?
Alleen de code uit __init__.py van dat package wordt uitgevoerd.
Wat is het verschil tussen de import “from . import mod1” en “import mod1”?
from . import mod1 (relatieve import) werkt alleen binnen het package, terwijl de absolute import de module zoekt in sys.path, wat kan leiden tot naamsconflicten.
__init__.py bestandenNegatieve case: Modules met dezelfde namen in verschillende submappen zonder gebruik te maken van absolute imports. Een package verwijst naar een module die niet de bedoelde is. Voordelen:
Positieve case:
Duidelijk opgeven van absolute imports, juiste mapstructuur en aanwezigheid van __init__.py.
Voordelen: