programowanieProgramista backendowy

Opowiedz, co się dzieje, gdy moduł jest importowany w Pythonie. Jak Python wyszukuje i ładuje moduły? Jakie typowe błędy można popełnić przy niewłaściwej organizacji importów?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Gdy w Pythonie następuje import modułu, interpreter szuka go w katalogach wymienionych w sys.path. Najpierw szuka wśród standardowych modułów, następnie wśród plików .py, .pyc oraz katalogów zawierających plik __init__.py (pakiety).

  1. Jeśli moduł był już zaimportowany, powtórny import po prostu bierze go z sys.modules.
  2. Jeśli moduł nie zostanie znaleziony w standardowych ścieżkach, zostanie zgłoszony wyjątek ModuleNotFoundError.
  3. Przy imporcie moduł jest tłumaczony na bajt-kod (.pyc) i buforowany (jeśli są odpowiednie uprawnienia do zapisu).

Przykład:

# mypkg/__init__.py (może być pusty) # mypkg/mod.py # main.py import mypkg.mod
  • Nazwa pliku, struktura katalogów, obecność/brak __init__.py (dla Pythona <3.3 obowiązkowa) — wszystko ma znaczenie.

Jak szuka:

  • Najpierw import absolutny.
  • Następnie — wyszukiwanie w katalogach sys.path (zawsze pierwszym jest katalog bieżącego skryptu).
  • W pakietach ważny jest kontekst (from . import ..., import absolutny/relatywny).

Pytanie z pułapką.

Co się stanie, jeśli w katalogu z twoim skryptem znajduje się plik o nazwie random.py i spróbujesz zaimportować standardowy moduł random?

Odpowiedź:

Zaimplementowany zostanie MÓJ lokalny plik random.py, a nie standardowa biblioteka. Częstą przyczyną trudnych do zdiagnozowania błędów są kolizje nazw modułów z bibliotekami (shadowing). Należy ostrożnie podchodzić do nazywania plików.

Przykłady rzeczywistych błędów z powodu braku znajomości szczegółów tematu.


Historia

W dużym projekcie moduł email.py przypadkowo zastąpił standardowy moduł email z biblioteki, a programiści przez długi czas nie mogli zrozumieć, dlaczego nie działają funkcje parsowania maili z zewnętrznych bibliotek.


Historia

W projekcie ML funkcja os.path nie działała: obok głównego skryptu był plik os.py, który przechwytywał wszystkie odwołania do standardowego modułu. Miesiąc spędzono na debugowaniu, zanim znaleziono konflikt nazw.


Historia

W mikroserwisowym REST API wystąpiły cykliczne importy przy próbie wykonania relatywnego importu modeli między różnymi podpakietami. Problem rozwiązano dopiero po refaktoryzacji struktury projektu i wyraźnym porządku ładowania modułów.