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 plikusys.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ątku calendar.py
pliku:
import sys
def copy_in_standard_module_symbols(name, local_module):
import imp
for i in range(0, 100):
random_name = 'random_name_%d' % (i,)
if random_name not in sys.modules:
break
else:
random_name = None
if random_name is None:
raise RuntimeError("Couldn't manufacture an unused module name.")
f, pathname, desc = imp.find_module(name, sys.path[1:])
module = imp.load_module(random_name, f, pathname, desc)
f.close()
del sys.modules[random_name]
for key in module.__dict__:
if not hasattr(local_module, key):
setattr(local_module, key, getattr(module, key))
copy_in_standard_module_symbols('calendar', sys.modules[copy_in_standard_module_symbols.__module__])