Pytanie Prawidłowe importowanie modułów w Pythonie


Jak skonfigurować import modułów, aby każdy moduł miał dostęp do obiektów wszystkich pozostałych?

Mam średniej wielkości aplikację Python z plikami modułów w różnych podkatalogach. Stworzyłem moduły, które dołączają te podkatalogi do sys.path i importuje grupę modułów, używając import thisModule as tm. Obiekty modułu odnoszą się do tej kwalifikacji. Następnie zaimportuję ten moduł do innych przy pomocy from moduleImports import *. Kod jest teraz niechlujny i zawiera kilka z tych rzeczy, które często są duplikowane.

Po pierwsze, aplikacja nie działa, ponieważ niektóre odwołania do modułów nie są przypisane. Ten sam kod działa po przetestowaniu urządzenia.

Po drugie, martwię się, że powoduję problem z importem modułów rekurencyjnych. Importowanie modułu Import importuje ten moduł, który importuje moduł import_portu. . . .

Jaki jest właściwy sposób na zrobienie tego?


10
2018-05-22 02:09


pochodzenie


Nie wiem, czy to bezpośrednio odpowiada na twoje pytanie, ale Pytałem o importowanie kilka dni temu. Znalazłem odpowiedzi bardzo pomocne. - John Pirie


Odpowiedzi:


"Mam średniej wielkości aplikację Pythona z plikami modułów w różnych podkatalogach."

Dobry. Upewnij się, że każdy katalog zawiera a __init__.py plik, więc jest to pakiet.

"Stworzyłem moduły, które dołączają te podkatalogi do sys.path"

Zły. Posługiwać się PYTHONPATH lub zainstaluj całą strukturę Lib/site-packages. Nie aktualizuj sys.path dynamicznie. To zła rzecz. Trudne w zarządzaniu i utrzymaniu.

"importuje grupę modułów, używając import thisModule as tm. "

Nie ma sensu. Być może masz jeden import thisModule as tm dla każdego modułu w twojej strukturze. Jest to typowa, standardowa praktyka: importuj tylko te moduły, których potrzebujesz, żadnych innych.

"Następnie zaimportuję ten moduł do innych from moduleImports import *"

Zły. Nie kopiuj zaimportuj paczki losowych rzeczy.

Każdy moduł powinien mieć długą listę konkretnych rzeczy, których potrzebuje.

import this
import that
import package.module

Jawna lista. Bez magii. Brak dynamicznej zmiany w sys.path.

Mój obecny projekt zawiera 100 modułów, kilkanaście pakietów. Każdy moduł importuje dokładnie to, czego potrzebuje. Bez magii.


22
2018-05-22 10:05



Zawijanie w jednym zdaniu: "jawny jest lepszy niż niejawny". - Jorge Leitão


Kilka wskaźników

  1. Być może już się podzieliłeś funkcjonalność w różnych modułach. Gdyby prawidłowo zrobione przez większość czasu nie wpadnie w okrągły import problemy (np. czy moduł a zależy na b i b na jednym możesz zrobić trzeci moduł c, aby usunąć taki okrągły zależność). W ostateczności, w import b ale w b import a na punkt, w którym jest potrzebne, np. wewnątrz funkcjonować.

  2. Gdy funkcjonalność jest poprawna moduły grupują je w pakiety w ramach a subdir i dodaj __init__.py plik do tego, aby można było zaimportować plik pakiet. Trzymaj takie pakunki w folder np. lib, a następnie albo dodaj do sys.path lub ustaw PYTHONPATH env zmienna

  3. z importu modułu * nie może być dobrym pomysłem. Zamiast tego importuj cokolwiek jest potrzebne. Może być w pełni kwalifikowany. To nie boli, aby być gadatliwym. na przykład z importu pakageA.moduleB CoolClass.


6
2018-05-22 02:20



Mała notka do formatowania: Wierzę, że masz na myśli w tym.py (użyj klawiszy wstecz, aby zapobiec przekształceniu na pogrubiony.) - Laurence Gonsalves
Dzięki, te proste języki formatowania stają się czasami trudne do zarządzania - Anurag Uniyal
Nie rozumiem, co masz na myśli przez "dzieloną funkcjonalność" ani w jaki sposób trzeci moduł pomógłby rozwiązać zależności między dwoma modułami. - chernevik
effbot.org/zone/import-confusion.htm może być pomocne - Anurag Uniyal


Sposobem na to jest unikanie magii. Innymi słowy, jeśli twój moduł wymaga czegoś z innego modułu, powinien zaimportować go jawnie. Nie powinieneś polegać na tym, że rzeczy są automatycznie importowane.

Jako Zen z Python (import this) ma to, wyraźne jest lepsze niż ukryte.


4
2018-05-22 09:10





Nie uzyskasz rekursji na importach, ponieważ Python buforuje każdy moduł i nie przeładuje tego, który już posiada.


3
2018-05-22 02:17



cykliczny import może się naprawdę stać, np. Przypuśćmy, że b definiuje funkcję, którą używa i wzajemnie się importuje copypastecode.com/codes/view/5193 - Anurag Uniyal
@Anurag Uniyal: czy faktycznie to testowałeś? import śledzi to, co importuje, więc nie ma gwarancji, że nawet ten kod spowoduje rekurencyjne ładowanie. - SpliFF
zdarza się, że nie pamiętam dokładnie szczegółów, ale ma coś wspólnego z tym samym modułem zaimportowanym dwa razy jako główny, a następnie moduł - Anurag Uniyal