Skip to content

Pakiety modułów

Wstęp

Moduł w Pythonie to plik z rozszerzeniem .py, który zawiera kod – może to być pojedyncza funkcja, klasa, a nawet cały zestaw narzędzi. Moduły pozwalają nam na przechowywanie kodu w osobnych plikach i łatwe jego importowanie oraz używanie w innych miejscach.

Kiedy używamy instrukcji import, Python próbuje znaleźć odpowiedni moduł w określonych lokalizacjach, które są przechowywane w zmiennej sys.path. Lista tych ścieżek obejmuje:

  • Bieżący katalog roboczy – katalog, z którego uruchamiamy skrypt.
  • Katalogi standardowe Pythona – ścieżki z bibliotekami standardowymi.
  • Katalogi specyficzne dla instalacji – katalogi, które mogą zawierać dodatkowe moduły lub pakiety, np. zainstalowane za pomocą pip.

U siebie możemy to zobaczyć używając:

import sys
print(sys.path)

Wprowadzenie do pakietów

Pakiet w Pythonie to katalog (folder) zawierający moduły. Pakiety pozwalają na hierarchiczne organizowanie kodu, co jest szczególnie użyteczne w większych projektach. Każdy pakiet jest katalogiem, który powinien zawierać plik __init__.py, aby Python mógł go rozpoznać jako pakiet.

Pakiety mogą być zagnieżdżane w innych pakietach, tworząc strukturę drzewiastą. Przykładowa struktura pakietu mogłaby wyglądać tak:

nasz-projekt/

├── src/
   ├── zajecia01/
         ├── __init__.py
         ├── dodawanie.py
         ├── odejmowanie.py
         └── dzielenie.py
   
   └── __init__.py

├── docs/

└── tests/

Pliki __init__.py

Jak widzimy w przykładowej strukturze powyżej, każdy katalog, który ma być rozpoznawany jako część pakietu, posiada ten plik. Początkowo, w starszych wersjach Pythona, ten plik był obowiązkowy; obecnie w Pythonie 3.x nadal jest używany, ale jego obecność nie jest wymagana do rozpoznania katalogu jako pakietu. Jednak __init__.py nadal ma ważne funkcje:

  • Inicjalizacja pakietu – Plik __init__.py jest uruchamiany przy pierwszym importowaniu pakietu, więc można w nim umieścić kod, który zostanie wykonany na początku.
  • Kontrolowanie importów – Możemy zdefiniować listę __all__ w __init__.py, aby kontrolować, które moduły zostaną zaimportowane, gdy użyjemy from pakiet import *.

Przykładowy plik __init__.py znajdujący się w zajęcia01:

__all__ = ["dodawanie", "odejmowanie"]

Dzięki temu przy from zajecia01 import * zostaną zaimportowane tylko moduły dodawanie i odejmowanie, podczas gdy dzielenie zostanie pominięte.

Importowanie modułów

Mamy 2 główne typy importu:

  • Import bezwzględny – polega na podaniu pełnej ścieżki do modułu lub pakietu, np. import kalkulator.dodawanie.
  • Import względny – używany jest wewnątrz pakietów i bazuje na kropkach wiodących:
    • Jedna kropka . oznacza bieżący pakiet.
    • Dwie kropki .. oznaczają pakiet nadrzędny.
Warning

Import względny działa tylko wtedy, gdy jesteśmy w kontekście pakietu, np. podczas importowania modułów wewnątrz innego modułu tego samego pakietu.

Przykład - importowanie bezwzględne
from zajecia01 import dodawanie, odejmowanie

print(dodawanie.dodaj(5, 3))  # Użycie funkcji dodaj z modułu dodawanie
print(odejmowanie.odejmij(5, 3))  # Użycie funkcji odejmij z modułu odejmowanie
Przykład - importowanie względne (wewnątrz pakietu)

Będąc w pliku zajecia01/mnozenie.py

from .dodawanie import dodaj  # Import z bieżącego pakietu

def mnoz(a, b):
    wynik = 0
    for _ in range(b):
        wynik = dodaj(wynik, a)  # Użycie funkcji dodaj
    return wynik

Zadania

  1. Wykorzystując aktualną strukturę repozytorium, stwórz w głównym katalogu plik run.py, zaimportuj do niego wybrane funkcje / klasy i wywołaj przykładowy kod z ich użyciem.

Tip

Nie zapomnij dodać plików __init__.py wewnątrz pakietów, a także list __all__ w tych plikach.