2010-06-29 67 views
55

我剛剛加入了一個項目,其代碼庫相當龐大。我們在linux中開發,不使用IDE。我們通過命令行運行。我試圖找出如何讓python在運行項目模塊時搜索正確的路徑。舉例來說,當我運行類似:展開Python搜索其他源代碼的路徑

python someprojectfile.py 

我得到

ImportError: no module named core.'somemodule' 

我得到這個我的所有進口到我想這是與路徑的問題。

TLDR:

我如何讓Python中導入語句搜索~/codez/project/和所有的* .py文件的文件和文件夾。

回答

95

有幾種可能的方式來做到這一點:

  • 設置環境變量PYTHONPATH到目錄搜索導入模塊的冒號分隔的列表。
  • 在你的程序中,使用sys.path.append('/path/to/search')添加想要的Python搜索導入模塊目錄的名稱。 sys.path只是Python每次被要求導入模塊時搜索的目錄列表,並且可以根據需要進行更改(儘管我不建議刪除任何標準目錄!)。 Python啓動時,將放入環境變量PYTHONPATH中的任何目錄都將插入到sys.path中。
  • 使用site.addsitedir到一個目錄添加到sys.path。這只是普通的追加之間的區別是,當你使用addsitedir,它還會查找該目錄中.pth文件,並使用它們基於文件的內容sys.path到可能添加額外的目錄。請參閱文檔以獲取更多細節。

其中哪些你想用一個取決於你的情況。請記住,當你發佈你的項目給其他用戶,他們通常以這樣的方式使Python代碼文件將通過Python的進口商可以自動檢測(即包通常安裝在site-packages目錄),安裝它,這樣,如果你惹sys.path在你的代碼,這可能是不必要的,甚至可能在代碼在另一臺計算機上運行時產生不利影響。對於開發,我會冒險猜測設置PYTHONPATH通常是最好的方法。

然而,當你正在使用的東西,只是你自己的計算機上運行(或者當你有非標準的設置,例如有時在Web應用程序框架),它不是完全少見做這樣的事情

from os.path import dirname 
sys.path.append(dirname(__file__)) 
+0

因此,如果我想說15個子目錄,我將不得不分別添加每個子目錄? – themaestro 2010-06-29 19:46:37

+0

並且你能給一個命令行參數的例子來改變PYTHONPATH嗎? – themaestro 2010-06-29 19:49:06

+2

要在'.bashrc'中設置'PYTHONPATH':或者你的shell使用的任何啓動文件(如果它不是Bash),寫'export PYTHONPATH = $ PYTHONPATH:$ HOME/codez/project'。但是如果你有一堆子目錄,我會創建一個'.pth'文件並使用'site.addsitedir'。你可以創建一個模塊'sitecustomize'來爲你調用函數;嘗試把它放在'〜/ .local/lib/python2.6/sitecustomize.py'(替換你的Python版本),以便它能夠自動導入。 – 2010-06-29 19:54:56

9

你還應該在這裏閱讀關於Python包:http://docs.python.org/tutorial/modules.html

從你的榜樣,我猜你真的有一個包在~/codez/project。 Python目錄中的文件__init__.py將目錄映射到命名空間。如果您的子目錄都有__init__.py文件,那麼您只需將基礎目錄添加到您的PYTHONPATH。例如:

PYTHONPATH = $ PYTHONPATH:$ HOME/adaifotis /項目

除了測試您的PYTHONPATH環境變量,如大衛解釋說,你可以測試它在Python這樣的:

$ python 
>>> import project      # should work if PYTHONPATH set 
>>> import sys 
>>> for line in sys.path: print line # print current python path 

...

+0

您可能想要將'__init __。py'放入反引號中,以表明您確實是指'__init __。py',而不是'init.py'。只是爲了避免混淆新手。 :) – antred 2015-02-19 14:38:36

2

我看這個問題尋找答案,並沒有像任何人。

所以我寫了一個快速和骯髒的解決方案。只要把這個地方你的sys.path中,它會folder下添加任何目錄(從當前工作目錄),或在abspath

#using.py 

import sys, os.path 

def all_from(folder='', abspath=None): 
    """add all dirs under `folder` to sys.path if any .py files are found. 
    Use an abspath if you'd rather do it that way. 

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree. 
    With that, try not to use this on something too close to '/' 

    """ 
    add = set(sys.path) 
    if abspath is None: 
     cwd = os.path.abspath(os.path.curdir) 
     abspath = os.path.join(cwd, folder) 
    for root, dirs, files in os.walk(abspath): 
     for f in files: 
      if f[-3:] in '.py': 
       add.add(root) 
       break 
    for i in add: sys.path.append(i) 

>>> import using, sys, pprint 
>>> using.all_from('py') #if in ~, /home/user/py/ 
>>> pprint.pprint(sys.path) 
[ 
#that was easy 
] 

而且我喜歡它,因爲我可以有一些文件夾隨機工具,而不是將它們作爲軟件包或任何其他軟件的一部分,仍然可以通過幾行代碼訪問其中的一些(或全部)工具。

1

我找到的最簡單的方法是創建一個文件「any_name.pth」並將它放在文件夾「\ Lib \ site-packages」中。無論你安裝了python,你都應該找到該文件夾​​。

在該文件中,放置一個您想保留模塊以供導入的目錄列表。例如,使在該文件中這樣一行:

C:\用戶\例如... \例如

您將能夠告訴它的工作原理是在Python運行以下命令:

import sys 
for line in sys: print line 

你會看到你的目錄打印出來,除此之外你也可以導入。現在,您可以導入「mymodule.py」文件,該文件在那個目錄中輕鬆地坐在爲:

import mymodule 

這將不導入子文件夾。爲此,您可以想象創建一個python腳本來創建一個.pth文件,該文件包含您定義的文件夾的所有子文件夾。也許它在啓動時運行。

1

我知道這個帖子有點舊了,但是花了一些時間纔得到這個的核心,所以我想分享一下。

在我的項目中,我在父目錄中有主腳本,並且爲了區分這些模塊,我將所有支持模塊放在一個名爲「modules」的子文件夾中。在我的主腳本,我導入這些模塊就像這樣(的模塊調用report.py):

從modules.report進口報告,reportError

如果我把我的主腳本,這個工程。不過,我想通過包括一個main()中的每個,並調用每個直接,以測試每個模塊:

Python模塊\ report.py

現在的Python抱怨說,它無法找到「模塊所謂的模塊「。這裏的關鍵是,默認情況下,Python在其搜索路徑中包含腳本的文件夾,但不包括CWD。所以這個錯誤說的真的是「我找不到模塊子文件夾」。這是因爲report.py模塊所在的目錄沒有「modules」子目錄。

我覺得最巧妙的解決方案,這是由包括這個頂部將追加在Python搜索路徑的CWD:(「」)

進口SYS

sys.path.append

現在Python搜索CWD(當前目錄),找到「modules」子文件夾,一切正常。