簡體   English   中英

從__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 somemodulefrom 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 然后在將來的某個時間將其刪除。

可以做

以下想法是基於import語句的文檔中信息。

首先檢查的是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM