Doświadczenie dotyczące nowych haków importowych PEP-302 Pythona [zamknięte]

40

Jestem jednym z programistów Ruby (CRuby). Pracujemy nad wydaniem Ruby 2.0 (planowane wydanie 2012 / luty).

Python ma „PEP302: Nowe haki importowe” (2003):

Ten PEP proponuje dodanie nowego zestawu zaczepów importowych, które oferują lepszą personalizację mechanizmu importu Python. W przeciwieństwie do obecnego haka importu, haczyk w nowym stylu można wstrzyknąć do istniejącego schematu, co pozwala na dokładniejszą kontrolę tego, jak moduły są wyszukiwane i jak są ładowane.

Rozważamy wprowadzenie funkcji podobnej do PEP302 w Ruby 2.0 (CRuby 2.0). Chcę złożyć propozycję, która może przekonać Matza. Obecnie CRuby może ładować skrypty tylko z systemów plików w standardowy sposób.

Jeśli masz jakieś doświadczenie lub uwagi na temat PEP 302, udostępnij je.

Przykład:

  1. To świetna specyfikacja. Nie trzeba tego zmieniać.
  2. Jest prawie dobry, ale ma ten problem ...
  3. Gdybym mógł wrócić do 2003 roku, zmieniłbym specyfikację na ...
Koichi Sasada
źródło
6
Wow, sam facet YARV, cześć i witam w Programistach! ;) Na Stack Exchange naprawdę nie lubimy otwartej dyskusji, zamiast tego uwielbiamy rozwiązywać określone problemy (przeczytaj szybko nasze FAQ ) - zgaduję, że właśnie dlatego twoje pytanie zostało zamknięte na przepełnieniu stosu i ma już zamknij głosowanie tutaj. Powinieneś spróbować, aby uczynić to nieco bardziej szczegółowym - czy masz jakieś obawy dotyczące PEP 302, które uzasadniły to pytanie?
yannis
4
Dziękuję za komentarz, Yannis. Myślę, że chcę porozmawiać o „architekturze oprogramowania”. PEP302 wydaje się potężną i ogólną strukturą do rozszerzenia własnych programów ładujących na interpreter Pythona. Jednak potężna funkcja wiąże się z ryzykiem, takim jak nadużywanie (generowanie magicznych kodów), co uniemożliwia optymalizację interpretera. Chcę więc wiedzieć, że ta struktura rozszerzeń jest słodka dla użytkowników Pythona i programistów interpreterów. Wierzę, że studiowanie historii pomoże mi dobrze opracować specyfikację Ruby 2.0.
Koichi Sasada
Dziękuję, zmieniając moje pytanie. Przykro mi, jeśli to pytanie nie jest lepsze.
Koichi Sasada
To fantastyczny przykład tego, w jaki sposób pytanie, które pojawia się na powierzchni, nie zdaje egzaminu „sondażowego”, może jednak mieć niesamowitą wartość.
Ross Patterson

Odpowiedzi:

47

Jestem opiekunem modułowego modułu Pythona i jednym z opiekunów bieżącego systemu importu. Chociaż nasz system importowania jest imponująco elastyczny, odradzam wprowadzanie go w sprzedaży hurtowej bez wprowadzania kilku drobnych poprawek - ze względu na problemy z kompatybilnością wsteczną istnieje wiele rzeczy, które są bardziej niezręczne niż byłyby konieczne.

Jedną z rzeczy, która bolała PEP 302 w Pythonie, było to, ile czasu zajęło nam przekonwertowanie podstawowego systemu importu na jego użycie. Przez większą część dekady każdy, kto robi coś skomplikowanego z hakami importowymi, utknął przy wdrażaniu dwóch elementów: jednego obsługującego moduły ładujące zgodne z PEP 302 (takiego jak import zip), a drugiego obsługującego standardowy mechanizm importu oparty na systemie plików. Dopiero w nadchodzącej wersji 3.3 obsługa modułów ładujących PEP 302 zajmie się także obsługą modułów importowanych przez standardowy mechanizm importu systemu plików. Staraj się nie powtarzać tego błędu, jeśli możesz go uniknąć.

PEP 420 (zaimplementowany w Pythonie 3.3) wprowadza pewne poprawki do protokołu, aby umożliwić importerom dodanie części do pakietów przestrzeni nazw. Naprawiono także problem z nazewnictwem w definicji API Findera (skutecznie zastępując błędnie nazwany „moduł_wyszukiwania” bardziej dokładnym „moduł_wyszukiwania”). Mam nadzieję, że wszystko to powinno być udokumentowane jaśniej w specyfikacji językowej do czasu, gdy 3.3rc1 pojawi się za kilka tygodni.

Innym znaczącym problemem jest to, że podejście udokumentowane konkretnie w PEP 302 ma zdecydowanie za dużo stanu globalnego procesu. Nie podążaj za nami tą ścieżką - spróbuj enkapsulować stan w bardziej spójnym modelu obiektowym, aby nieco łatwiej było selektywnie importować inne moduły (moduły rozszerzeń C są zmorą uczynienia takiej enkapsulacji całkowicie skuteczną, ale nawet pewnym poziomem enkapsulacji może być pomocne).

PEP 406 (http://www.python.org/dev/peps/pep-0406/) omawia możliwą wsteczną kompatybilną ewolucję podejścia Pythona z ulepszoną enkapsulacją stanu. Jeśli jednak masz model enkapsulowany od samego początku, możesz odpowiednio zdefiniować interfejsy API i uniknąć w ogóle dostępu importerów i ładujących do stanu globalnego (zamiast przekazywania odniesienia do aktywnego silnika).

Kolejnym brakującym elementem w PEP 302 jest możliwość zwrócenia się do importera o iterator w stosunku do modułów dostarczonych przez tego importera (jest to konieczne do takich rzeczy, jak narzędzia do zamrażania i narzędzia do automatycznej dokumentacji, które wyodrębniają dokumenty). Ponieważ jest niezwykle przydatny, prawdopodobnie lepiej byłoby ujednolicić go od samego początku: http://docs.python.org/dev/library/pkgutil#pkgutil.iter_modules (prawdopodobnie ostatecznie podniesiemy to do formalnie określonego API w Python 3.4)

I mój ostatni komentarz jest taki, że powinieneś dokładnie przyjrzeć się podziałowi odpowiedzialności między systemem importu a obiektami modułu ładującego. W szczególności rozważ podzielenie API „load_module” na osobne kroki „init_module” i „exec_module”. Powinno to pozwolić na zminimalizowanie stopnia, w jakim moduły ładujące muszą bezpośrednio oddziaływać ze stanem importu.

PEP 302 i importlib to świetny punkt wyjścia do bardziej elastycznego systemu importu, ale zdecydowanie popełniamy błędy, których warto unikać.

ncoghlan
źródło
1
Oni nie dość jeszcze gotowy, ale wstępny projekt docs pełny system import można znaleźć na docs.python.org/dev/reference/import
ncoghlan
1
python.org/dev/peps/pep-0451 jest aktualizacja do systemu przywozu Pythona dla Pythona 3.4, który odnosi się do wielu uwag Brett i ja tutaj.
ncoghlan
28

Obok ncoghlan jestem drugim opiekunem systemu importu Pythona i autorem jego bieżącej implementacji importlib (http://docs.python.org/dev/py3k/library/importlib.html). Wszystko, co Nick powiedział, zgadzam się, więc chcę tylko dodać dodatkowe informacje.

Po pierwsze, nie polegaj zbytnio bezpośrednio na PEP 302, ale zamiast tego spójrz na to, co zapewnia importlib w kategoriach abstrakcyjnych klas bazowych itp. Dla kompatybilności wstecznej rzeczy musiały być kompatybilne z PEP 302, ale musiałem dodać trochę moich własne interfejsy API, aby zakończyć rozwijanie obsługi prawdziwej elastyczności.

Inną ważną kwestią jest to, że dajesz programistom dwa elementy elastyczności. Jedną z nich jest możliwość przechowywania kodu w sposób inny niż tylko bezpośrednio w systemie plików jako pojedyncze pliki (nazywam to zapleczem pamięci do importowania), np. Pozwala to na kod w pliku zip, bazie danych sqlite itp. Drugim wsparciem jest umożliwienie kontroli w pewien sposób kodu przed lub po przetworzeniu, np. Quixote (https://www.mems-exchange.org/software/quixote/) i jego alternatywne użycie literałów łańcuchowych nieprzypisanych do zmienna byłaby znacznie łatwiejsza do obsługi.

Podczas gdy ten drugi jest rzadko potrzebny, ten drugi jest miejscem, gdzie musisz się martwić o wsparcie. I tutaj kończy się praktycznie redefinicja interfejsów API interakcji systemu plików. Ponieważ niektóre osoby potrzebują zasobów przechowywanych jako pliki z ich kodem, musisz zapewnić dobry sposób czytania plików, odkrywania plików itp. Nadal musimy wdrożyć część interfejsu API w celu wykrycia, które pliki danych są dostępne, umieszczenia ich na liście itp. .

Ale wtedy potrzebujesz również interfejsów API specyficznych dla kodu. Jak wspomniał Nick, w końcu potrzebujesz interfejsów API do odkrycia, jakie moduły zawiera pakiet itp., Które nie są specyficzne dla plików. Istnieje dziwna dwoistość posiadania interfejsów API do obsługi modułów, w których wyodrębniono pojęcie plików, ale w końcu trzeba udostępnić interfejsy API, aby uzyskać dostęp do danych zasobów podobnych do plików. I gdy tylko spróbujesz wdrożyć jedno w odniesieniu do drugiego, aby uniknąć powielania, wody stają się naprawdę mętne (tzn. Ludzie polegają na oczekiwanej strukturze ścieżki pliku itp., Nie zwracając uwagi na fakt, że ścieżka może nie być prawdziwą ścieżką ponieważ dotyczy pliku zip zawierającego kod, a nie tylko plik). IOW będziesz musiał zaimplementować dwa podobne interfejsy API, ale na dłuższą metę będzie ci lepiej.

Jak powiedział Nick, nasze rozwiązanie jest dobrym punktem wyjścia, ale nie w ten sposób zrobiłbym to dzisiaj, gdybym projektował API od zera.

Brett Cannon
źródło
-1

PEP 302 umożliwia podpięcie się do mechanizmu importu Python, co oznacza, że ​​możesz importować kod z innych źródeł, takich jak bazy danych, pliki zip i tak dalej.

W implementacji importu w Pythonie istnieje długa historia złożoności, która wkrótce zostanie uproszczona poprzez wprowadzenie implementacji importu w Pythonie.

Powinienem doradzać długie i intensywne myślenie o narożnych skrzynkach. Wtedy prawdopodobnie uzyskasz przydatną implementację.

Holdenweb
źródło