Sytuacja: - W moim folderze_projektów znajduje się moduł o nazwie calendar - Chciałbym użyć wbudowanej klasy Calendar z bibliotek Pythona - Kiedy używam kalendarza Import Calendar, narzeka, ponieważ próbuje załadować z mojego modułu.
Przeprowadziłem kilka wyszukiwań i nie mogę znaleźć rozwiązania mojego problemu.
- Jak uzyskać dostęp do modułu biblioteki standardowej w Pythonie, gdy istnieje moduł lokalny o tej samej nazwie?
- http://docs.python.org/whatsnew/2.5.html
- Jak uniknąć ciągłego wpisywania nazwy modułu podczas importowania modułu w Pythonie?
Jakieś pomysły bez konieczności zmiany nazwy mojego modułu?
Odpowiedzi:
Przyjęte rozwiązanie zawiera obecnie przestarzałe podejście.
Dokumentacja importlib tutaj podaje dobry przykład bardziej odpowiedniego sposobu ładowania modułu bezpośrednio ze ścieżki pliku dla pythona> = 3.5:
Możesz więc załadować dowolny plik .py ze ścieżki i ustawić nazwę modułu na dowolną. Więc po prostu dostosuj
module_name
dowolną niestandardową nazwę, jaką ma mieć moduł podczas importowania.Aby załadować pakiet zamiast pojedynczego pliku,
file_path
powinna być ścieżką do katalogu głównego pakietu__init__.py
źródło
file_path=r"C:\Users\My User\My Path\Module File.py"
. Potem zadzwoniłemmodule_name
tak jak wydany moduł, dzięki czemu miałem pełny działający skrypt, który po usunięciu tego fragmentu mógł być używany na innych komputerachZmiana nazwy modułu nie jest konieczna. Zamiast tego, aby zmienić zachowanie importu, możesz użyć bezwzględnego importu. Na przykład za pomocą stem / socket.py importuję moduł gniazda w następujący sposób:
Działa to tylko z Pythonem 2.5 i nowszymi; umożliwia zachowanie, które jest domyślne w Pythonie 3.0 i nowszych. Pylint będzie narzekał na kod, ale jest on całkowicie prawidłowy.
źródło
PYTHONPATH
. Kolejne pytanie pokazuje, jak rozwiązać ten problem.Właściwie rozwiązanie tego jest dość łatwe, ale implementacja zawsze będzie nieco krucha, ponieważ zależy to od wewnętrznych mechanizmów importu Pythona i mogą one ulec zmianie w przyszłych wersjach.
(poniższy kod pokazuje, jak załadować lokalne i nielokalne moduły i jak mogą one współistnieć)
Najlepszym rozwiązaniem, jeśli to możliwe, jest unikanie nazywania modułów o takiej samej nazwie, jak nazwy bibliotek standardowych lub wbudowanych modułów.
źródło
sys.modules
późniejszymi próbami załadowania modułu lokalnego?Jedynym sposobem rozwiązania tego problemu jest samodzielne przejęcie wewnętrznej maszyny importowej. Nie jest to łatwe i wiąże się z ryzykiem. Za wszelką cenę powinieneś unikać latarni w kształcie Graala, ponieważ niebezpieczeństwo jest zbyt niebezpieczne.
Zamiast tego zmień nazwę modułu.
Jeśli chcesz się dowiedzieć, jak przejąć wewnętrzne maszyny importujące, oto, gdzie możesz się dowiedzieć, jak to zrobić:
Czasami są dobre powody, by wpaść w to niebezpieczeństwo. Powód, dla którego podajesz, nie znajduje się wśród nich. Zmień nazwę modułu.
Jeśli wybierzesz niebezpieczną ścieżkę, jednym z problemów, które napotkasz, jest to, że po załadowaniu modułu otrzymuje on „oficjalną nazwę”, dzięki czemu Python może uniknąć konieczności ponownego analizowania zawartości tego modułu. Mapowanie „oficjalnej nazwy” modułu do samego obiektu modułu można znaleźć w pliku
sys.modules
.Oznacza to, że jeśli jesteś
import calendar
w jednym miejscu, dowolny importowany moduł będzie traktowany jako moduł z oficjalną nazwącalendar
i wszystkimi innymi próbamiimport calendar
dowolnego miejsca, w tym w innym kodzie, który jest częścią głównej biblioteki Pythona, otrzyma ten kalendarz.Możliwe byłoby zaprojektowanie importera klienta przy użyciu modułu imputil w Pythonie 2.x, który powodowałby, że moduły ładowane z określonych ścieżek szukały modułów, które importowały w czymś innym niż
sys.modules
pierwszy lub coś podobnego. Ale jest to niezwykle skomplikowana rzecz, a i tak nie zadziała w Pythonie 3.x.Jest bardzo brzydka i okropna rzecz, którą możesz zrobić, która nie wymaga podpięcia mechanizmu importu. To jest coś, czego prawdopodobnie nie powinieneś robić, ale prawdopodobnie zadziała. Zmienia Twój
calendar
moduł w hybrydę modułu kalendarza systemowego i modułu kalendarza. Podziękowania dla Boaz Yaniv za szkielet funkcji, z której korzystam . Umieść to na początkucalendar.py
pliku:źródło
code
modułu std Pythona ), co oznacza, że tylko ułamek programistów może kiedykolwiek mieć jakiekolwiek problemy z tym „hackiem scalającym”. Użytkownicy nie byliby w ogóle dotknięci.Chciałbym zaoferować moją wersję, która jest połączeniem rozwiązania Boaz Yaniv i Omnifarious. Zaimportuje systemową wersję modułu, z dwiema głównymi różnicami w stosunku do poprzednich odpowiedzi:
Umieść to w miejscu dostępnym, abyś mógł to nazwać (mam mój w moim pliku __init__.py):
Przykład
Chciałem zaimportować mysql.connection, ale miałem już lokalny pakiet o nazwie mysql (oficjalne narzędzia mysql). Aby więc pobrać złącze z systemowego pakietu mysql, wymieniłem to:
Z tym:
Wynik
źródło
Zmień ścieżkę importu:
źródło
sys.modules
i nie zaimportuje ponownie modułu o tej samej nazwie.