2010-05-17 78 views
3

我有一個關於分佈在多個目錄中的單個模塊的問題。Python從分佈在不同目錄的包中訪問模塊

比方說,我有這兩個文件和目錄:

~/lib/python 
    xxx 
     __init__.py 
     util 
     __init__.py 
     module1.py 
     module2.py 
~/graphics/python 
    xxx 
     __init__.py 
     misc 
     __init__.py 
     module3.py 
     module4.py 

所以後來在我的Python模塊,我這樣做:

import sys 
pythonlibpath = '~/lib/python' 
if pythonlibpath not in sys.path: sys.path.append(pythonlibpath) 
import xxx.util.module1 

其中工程。現在

,問題是,我需要xxx.misc.module3,所以我這樣做:

import sys 
graphicslibpath = '~/graphics/python' 
if graphicslibpath not in sys.path: sys.path.append(graphicslibpath) 
import xxx.misc.module3 

,但我得到這個錯誤:

ImportError: No module named misc.module3 

好像它在某種程度上還記得在〜/ lib/python中有一個xxx包,然後嘗試從那裏找到misc.module3。

我該如何解決這個問題?

回答

2

你不能沒有極端的欺騙,將一個包裝結構拉入另一個。 Python要求包中的所有模塊都在一個子目錄下。請參閱os來源瞭解它如何處理os.path

1

Python確實記得有一個xxx包。爲了達到可接受的性能,這是非常必要的,一旦模塊和包被加載,它們被緩存。您可以通過查看字典sys.modules來查看哪些模塊已加載。

sys.modules是一個正常的字典,以便您可以刪除一個包從它,迫使它重新加載象下面這樣:

import sys 
print sys.modules 
import xml 
print sys.modules 
del sys.modules['xml'] 
print sys.modules 

注意導入xml包它是字典之後,但它是可能的將它從字典中刪除。這是我僅爲了教學目的而提出的一點,我不會在真實應用中推薦這種方法。此外,如果您需要將您的miscutil包裝在一起,這不會很好。如果可能的話重新安排你的源代碼結構以更好地適應普通的Python模塊加載機制。

1

這是由Python 3.3中的隱式命名空間包解決的。見PEP-420

+0

這似乎是python 3的正確答案,雖然有一個工作示例的解釋會很有用。 – funseiki 2018-02-16 18:37:14

0

這是改編的answer to a similar question

繼續@ Gary的回答,PEP 420 page表示在共享的__init__.py包中使用以下代碼。

__init__.py

from pkgutil import extend_path 
__path__ = extend_path(__path__, __name__) 

此代碼應被置於其內的XXX目錄的__init__.py。 見* S下方

someroot/ 
├── graphics 
│   └── python 
│    └── xxx 
│     ├── ****__init__.py**** 
│     └── misc 
│      ├── __init__.py 
│      ├── module3.py 
│      └── module4.py 
└── lib 
    └── python 
     └── xxx 
      ├── ****__init__.py**** 
      └── util 
       ├── __init__.py 
       ├── module1.py 
       └── module2.py 

一些setup.sh文件添加到Python的路徑:

libPath=someroot/lib/python/ 
graphicsPath=someroot/graphics/python/ 
export PYTHONPATH=$PYTHONPATH:$libPath:$graphicsPath 

的Python測試代碼(使用pyenv Python版本2.7.14和3.6.4測試):

import xxx.util.module1 
import xxx.misc.module3 # No errors