[英]Python - access module from package that is not imported through __init__.py?
[英]import from a module imported in __init__.py
我以前有以下結構(作為一個較大的項目的一部分):
lib/
__init__.py
somemodule.py
__init__.py
為空, somemodule.py
包含一些方法def hello()
。 現在,在我的所有代碼存儲庫中,都有該方法的大量導入,特別是from lib.somemodule import hello
。
由於各種原因,我現在希望將somemodule.py
移到子包中。 意思是,我希望結構為:
lib/
sublib/
__init__.py
somemodule.py
__init__.py
並弄清楚,如果現在lib/__init__.py
將包含: from sublib import somemodule
, from lib.somemodule import hello
運行仍然可以工作(本質上,現在使結構更改“透明”)。
但是,如果from lib.somemodule import hello
運行某些外部代碼,則錯誤ImportError: No module named somemodule
from lib import somemodule
運行時, from lib import somemodule
引發ImportError: No module named somemodule
。
我很樂意為我做錯事情的解釋,以及有關如何from lib.somemodule import hello
運行的任何建議,盡管文件夾結構發生了變化。
如果from lib.somemodule import hello
正常工作,則需要在包lib
有一個名為somemodule
的模塊。 from sublib import somemodule
調用只會將您的模塊添加到包的作用域中,而不會定義導入機制可以找到的新模塊。 這也是from lib import somemodule
起作用的原因。 它僅從軟件包lib
導入全局變量somemodule
。
因此,具有內容的模塊lib/somemodule.py
from .sublib.somemodule import *
將是解決該問題的最簡單,最干凈的方法,也許包括某種DeprecationWarning 。 然后在將來的某個時間將其刪除。
首先檢查的是
sys.modules
,它是先前已導入的所有模塊的緩存。
因此,一個簡單的可以做的解決方案是自己寫的模塊緩存:
import sys
from .sublib import somemodule
sys.modules[__package__+'.somemodule'] = somemodule
也許將查找程序添加到sys.meta_path
可能會更干凈一些:
import sys
from .sublib import somemodule
class SomemoduleFinder(object):
def find_module(self, fullname, path=None):
if fullname == __package__+'.somemodule':
return self
def load_module(self, fullname):
return somemodule
sys.meta_path.append(SomemoduleFinder())
如果您之前進行過設置,而lib/__init__.py
並未直接導入somemodule
,則還可以將導入內容放入SomemoduleFinder.load_module
方法中以反映該行為。 雖然這僅對我適用於Python 2。
查看Python模塊導入-顯式和隱式相對導入,以防止將來移植到Python 3時出現可移植性問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.