簡體   English   中英

與站點包沖突時,從當前目錄中的子包導入模塊

[英]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/ba目錄,以及當前目錄本身。

如果我將第一個目錄重命名為z則本地導入有效(對於zb以及適當地更改了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也不是軟件包。

  • 這意味着asite-packages不應該包下去,但...

  • site中存在一個.pth文件,該文件會強制將abcsite-packages復制為軟件包。

在這一點上,我不確定您想做什么來覆蓋它。 聽起來您想變得很駭客,並從sys.modules刪除現有軟件包,然后強行插入您自己的軟件包或類似的東西。 當然,您可以這樣做,如果您自己無法猜到的話,我可以向您顯示代碼。 (或者,您可能希望搜索numpy_override ,也可以使用類似的技巧,以用於已預先安裝了numpy或已通過系統重新安裝numpy 。)但是,我認為您最好這樣做首先重新考慮您的問題。 例如,為什么不構建一個包含您的軟件包而不是其site-packages中的system site-packages軟件包的virtualenv

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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