[英]Python: importing a sub-package module from both the sub-package and the main package
[英]Importing module from sub-package in current directory when it clashes with site-packages
我的site-packages
目錄中的abcd
軟件包中有模塊e
:
/usr/lib/python2.7/site-packages/a/b/c/__init__.py
/usr/lib/python2.7/site-packages/a/b/c/d/__init__.py
/usr/lib/python2.7/site-packages/a/b/c/d/e.py
兩種情況下__init__.py
均為空。 我將此目錄結構鏡像到當前目錄中:
a/b/c/__init__.py
a/b/c/d/__init__.py
a/b/c/d/e.py
我運行python 2.7並輸入:
from a.b.c.d.e import foo
site-packages
版本將被導入,而不是本地版本。 sys.path[0]
是空字符串。 我期望並因此在documentation / Google中找到當前目錄的優先級。 我也嘗試添加__init__.py
在當前目錄下的a/b
和a
目錄,以及當前目錄本身。
如果我將第一個目錄重命名為z
則本地導入有效(對於z
和b
以及適當地更改了import語句,都使用了額外的__init__.py
s)。
site-packages
包含abc-VERSION-nspkg.pth
:
import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('a',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('a',types.ModuleType('a')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p) import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('a', 'b')); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('a.b',types.ModuleType('a.b')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p); m and setattr(sys.modules['a'], 'b', m)
為什么不能這樣覆蓋模塊? 可能是因為sys.modules
已經包含該模塊了嗎? 我可以強迫它以某種方式被覆蓋嗎?
根據您的評論,問題是:
您的a
不是包,因為在Python 3.3之前,沒有__init__.py
文件的目錄永遠不是包。 這意味着您的abc
也不是軟件包。
這意味着a
在site-packages
不應該包下去,但...
site
中存在一個.pth
文件,該文件會強制將abc
的site-packages
復制為軟件包。
在這一點上,我不確定您想做什么來覆蓋它。 聽起來您想變得很駭客,並從sys.modules
刪除現有軟件包,然后強行插入您自己的軟件包或類似的東西。 當然,您可以這樣做,如果您自己無法猜到的話,我可以向您顯示代碼。 (或者,您可能希望搜索numpy_override
,也可以使用類似的技巧,以用於已預先安裝了numpy
或已通過系統重新安裝numpy
。)但是,我認為您最好這樣做首先重新考慮您的問題。 例如,為什么不構建一個包含您的軟件包而不是其site-packages
中的system site-packages
軟件包的virtualenv
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.