Storia della domanda: I pacchetti sono stati introdotti in Python per strutturare grandi basi di codice e per il riutilizzo del codice. Consentono di suddividere un progetto in moduli logici e facilitano la manutenzione e l'importazione delle funzionalità necessarie.
Problema: Una comprensione errata della struttura dei pacchetti porta a errori di importazione, conflitti di nomi ed errori nell'esecuzione degli script. È importante conoscere la differenza tra pacchetti e moduli, così come le regole per lavorare con importazioni relative e assolute.
Soluzione:
Un pacchetto è qualsiasi directory che contiene un file __init__.py (vuoto o con codice di inizializzazione). I pacchetti possono contenere altri pacchetti e moduli. Esempio di struttura:
project/
├── mypackage/
│ ├── __init__.py
│ ├── mod1.py
│ └── subpackage/
│ ├── __init__.py
│ └── mod2.py
└── script.py
Per importare utilizziamo un percorso relativo (from .subpackage import mod2) o assoluto (from mypackage.subpackage import mod2). Gli assoluti sono preferibili per progetti di grandi dimensioni.
Caratteristiche chiave:
__init__.pyDeve necessariamente essere presente init.py in ogni cartella che vogliamo trasformare in pacchetto?
Sì, per Python sotto la 3.3; nelle versioni moderne di Python (3.3+) ci sono pacchetti namespace "impliciti", ma per la piena compatibilità si raccomanda comunque il file.
Cosa succede se importiamo un pacchetto invece di un modulo?
Verrà eseguito solo il codice presente in __init__.py di quel pacchetto.
Qual è la differenza tra l'importazione “from . import mod1” e “import mod1”?
from . import mod1 (importazione relativa) funziona solo all'interno del pacchetto, mentre l'importazione assoluta cerca il modulo in sys.path, il che può portare a conflitti di nomi.
__init__.pyCaso negativo: Moduli con lo stesso nome in diverse sottocartelle senza utilizzare importazioni assolute. Un pacchetto accede a un modulo diverso da quello previsto. Vantaggi:
Caso positivo:
Definizione esplicita di importazioni assolute, corretta struttura delle cartelle e presenza di __init__.py.
Vantaggi: