Historia pytania: Pakiety pojawiły się w Pythonie w celu strukturyzacji dużych baz kodowych i ponownego użycia kodu. Pozwalają one na dzielenie projektu na logiczne moduły i ułatwiają utrzymanie oraz importowanie niezbędnej funkcjonalności.
Problem: Nieprawidłowe zrozumienie działania pakietów prowadzi do błędów z importem, konfliktów nazw i błędów uruchamiania skryptów. Ważne jest, aby znać różnicę między pakietami a modułami, a także zasady pracy z importami względnymi i bezwzględnymi.
Rozwiązanie:
Pakiet to dowolny katalog z plikiem __init__.py (pustym lub z kodem inicjalizacyjnym). Pakiety mogą zawierać inne pakiety i moduły. Przykład struktury:
projekt/
├── mypackage/
│ ├── __init__.py
│ ├── mod1.py
│ └── subpackage/
│ ├── __init__.py
│ └── mod2.py
└── skrypt.py
Do importu używamy ścieżki względnej (from .subpackage import mod2) lub bezwzględnej (from mypackage.subpackage import mod2). Importy bezwzględne są preferowane w dużych projektach.
Kluczowe cechy:
__init__.pyCzy plik init.py musi być obecny w każdym folderze, który chcemy uczynić pakietem?
Tak, w Pythonie poniżej wersji 3.3; w nowoczesnych wersjach Pythona (3.3+) istnieją „niejawne” pakiety przestrzeni nazw, ale dla pełnej kompatybilności plik nadal jest zalecany.
Co się stanie, jeśli zaimportujemy pakiet, a nie moduł?
Wykonany zostanie tylko kod z pliku __init__.py tego pakietu.
Jaka jest różnica między importem „from . import mod1” a „import mod1”?
from . import mod1 (import względny) działa tylko w ramach pakietu, podczas gdy import bezwzględny szuka modułu w sys.path, co może prowadzić do konfliktów nazw.
__init__.pyNegatywny przypadek: Moduły z tymi samymi nazwami w różnych podfolderach bez użycia importów bezwzględnych. Do jednego modułu odnosi się nie ten pakiet, co planowano. Zalety:
Pozytywny przypadek:
Wyraźne określenie importów bezwzględnych, prawidłowa struktura folderów i obecność __init__.py.
Zalety: