Choć tworzenie własnych punktów zaczepienia dla importu było możliwe od czasu wprowadzenia modułu ihooks w Pythonie 1.3, to właściwie nikomu dostępny mechanizm nie odpowiadał, gdyż był bałaganiarski i zawiły. Pojawiało się wiele alternatywnych propozycji, takich, jak moduły imputil i iu, jednak żadna z nich nie zystała powszechnej akceptacji i nie pozwalała na łatwe użycie z poziomu kodu napisanego w C.
Dokument PEP 302 zapożycza pomysły od swoich poprzedników, szczególnie z modułu iu autorstwa Gordona McMillana. Do modułu sys dodano trzy nowe elementy:
sys.path_hooks jest listą obiektów wywoływalnych (zazwyczaj
będą to klasy). Każdy obiekt wywoływalny pobiera jako argument napis
zawierający ścieżkę i zwraca obiekt importera, który obsługuje importowanie
z tej ścieżki lub też, w przypadku gdy importowanie z podanej ścieżki nie
jest obsługiwane, generuje wyjątek ImportError.
sys.path_importer_cache zawiera cache z obiektem importera dla każdej ze
ścieżek, dzięki czemu lista sys.path_hooks musi zostać w całości przejrzana tylko
raz dla każdej ścieżki.
sys.meta_path jest listą zawierającą obiekty importujące, która jest przeglądana
przed sprawdzeniem sys.path. Początkowo lista ta jest pusta, jednak obiekty może do
niej dodać kod użytkownika. Obiekt dodany do tej listy może importować dodatkowe wbudowane
i zamrożone moduły.
Obiekt importera musi mieć jedną metodę, find_module(fullname, path=None). Jako fullname (pełna_nazwa) zostanie przekazana nazwa modułu lub pakietu, np. "string" czy "distutils.core". Metoda find_module() musi zwrócić obiekt loadera, który oferuje metodę load_module(fullname) -- odpowiada ona za utworzenie i zwrócenie odpowiedniego obiektu modułu.
Nieco uproszczony pseudokod, odpowiadający nowemu mechanizmowi importowania w Pythonie, wygląda więc następująco (szczegóły zawarte są w dokumencie PEP 302):
for mp in sys.meta_path:
ładowarka = mp(pełna_nazwa)
if ładowarka is not None:
<moduł> = ładowarka.load_module(pełna_nazwa)
for ścieżka in sys.path:
for pkt_zacz in sys.path_hooks:
try:
importer = pkt_zacz(ścieżka)
except ImportError:
# Wystąpił wyjątek ImportError, spróbuj inne punkty zaczepienia
pass
else:
ładowarka = importer.find_module(pełna_nazwa)
<moduł> = ładowarka.load_module(pełna_nazwa)
# Nie odnaleziono!
raise ImportError
Zobacz też:
Zajrzyj do Informacji na temat tej publikacji... aby pomóc w jej rozwoju.