2010-12-08 176 views
559

我有以下文件夾結構。從不同文件夾導入文件

application/app/folder/file.py

,我想導入file.py一些功能在駐留在

application/app2/some_folder/some_file.py

另一個Python的文件我已經試過

from application.app.folder.file import func_name

和一些其他各種嘗試,但迄今爲止我無法正常導入。我怎樣才能做到這一點?

+0

相關:http://stackoverflow.com/q/43476403/674039 – wim 2017-04-18 15:56:55

回答

691

默認情況下,你不能。在導入文件時,Python只搜索當前目錄,運行入口點腳本的目錄以及包含諸如軟件包安裝目錄等位置的文件(實際上它比這更復雜一點,但這涵蓋了大多數情況)。

但是,可以在運行時添加到Python的路徑:

# some_file.py 
import sys 
sys.path.insert(0, '/path/to/application/app/folder') 

import file 
+150

`sys.path.append( '/路徑/要/應用程序/應用程序/文件夾' )````更清潔imo – pseudosudo 2011-09-01 21:48:33

+218

@pseudosudo:是的,但是在開始時插入它有利於保證在命名衝突的情況下在其他人(甚至是內置的)之前搜索路徑。 – Cameron 2011-09-02 02:47:33

+0

現在,如果只有Python`lists`有一個`prepend`方法,那麼最好的選擇不會看起來難看。我明白「prepend」不存在的原因(因爲它的運行時間比'append`更糟糕),但這似乎是一個沒有實際意義的原因。不應該容易閱讀被重視快速運行? – ArtOfWarfare 2013-10-31 18:54:56

329

沒有錯:

from application.app.folder.file import func_name 

Just確保文件夾也包含一個__init__.py,這允許它被包含在一個包中。不知道爲什麼其他答案談論PYTHONPATH。

14

據我所知,直接在要導入的函數的文件夾中添加一個__init__.py文件即可完成這項工作。

12

考慮application的根目錄下爲你的Python項目,創建一個空__init__.py文件applicationappfolder文件夾。然後在你的some_file.py更改如下得到FUNC_NAME的定義:

import sys 
sys.path.insert(0, r'/from/root/directory/application') 

from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file. 
func_name() 
5

如果從特定路徑加載模塊的目的是自定義模塊的開發過程中爲您提供幫助,您可以創建一個符號鏈接到測試腳本的相同文件夾中,該文件夾指向自定義模塊的根目錄。對於在該文件夾中運行的任何腳本,此模塊引用將優先於安裝了相同名稱的其他任何模塊。

我在Linux上測試過它,但它應該可以在任何支持符號鏈接的現代操作系統中使用。

這種方法的一個優點是您可以指向一個模塊,它位於您自己的本地SVC分支工作副本中,可以大大簡化開發週期並減少管理不同版本模塊的失敗模式。

10

這對我的作品在python3爲我工作在Linux上的窗戶

# some_file.py on mainApp/app2 
import sys 
sys.path.insert(0, sys.path[0]+'\\app2') 

import some_file 
11

import sys 
sys.path.append(pathToFolderContainingScripts) 
from scriptName import functionName #scriptName without .py extension 
25

當模塊在平行的位置,如問題:

application/app2/some_folder/some_file.py 
application/app2/another_folder/another_file.py 

這種簡寫使一個模塊對另一個模塊可見:

import sys 
sys.path.append('../') 
5

你的問題是,Python正在尋找這個文件的Python目錄,但沒有找到它。你必須指定你正在談論你所在的目錄,而不是Python目錄。

要做到這一點,你改變這一點:

from application.app.folder.file import func_name

這樣:

from .application.app.folder.file import func_name 

通過增加你說的這個文件夾中查找應用程序文件夾的點,而不是看在Python目錄。

(希望這會解決您的問題!)

-1
sys.path.insert(0, '/path/to/application/app/folder') 
3

我很特別:我使用Python與Windows!我只是完整的信息:對於Windows和Linux,相對路徑和絕對路徑都工作到sys.path(我需要相對路徑,因爲我在幾臺PC上和不同的主目錄下使用我的腳本)。

而且在使用Windows時都\/可以作爲分隔符的文件名,當然你必須加倍\到Python字符串,
一些有效的例子:

sys.path.append('c:\\tools\\mydir') 
sys.path.append('..\\mytools') 
sys.path.append('c:/tools/mydir') 
sys.path.append('../mytools') 

(注:我認爲/\更方便,如果它比'Windows原生'更容易發生,因爲它與Linux兼容並且更容易寫入並複製到Windows資源管理器)

0

您可以通過按f5鍵刷新Python shell,或進入Run-> Run Module。這樣您就不必更改目錄以從文件中讀取某些內容。 Python會自動更改目錄。但是如果你想在Python Shell中使用不同目錄中的不同文件,那麼你可以在之前更改sys中的目錄as Cameron said

1

將sys.path.append與絕對路徑配合使用,在將應用程序移動到其他環境時並不理想。使用相對路徑並不總是有效,因爲當前工作目錄取決於腳本如何運行。

由於應用程序文件夾結構是固定的,我們可以使用os.path來獲取完整路徑。例如,如果這是結構:

/home/me/application/app2/some_folder/vanilla.py 
/home/me/application/app2/another_folder/mango.py 

假設您要導入「芒果」模塊。您可以在vanilla.py中執行以下操作:

import sys, os.path 
mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 
+ '/another_folder/') 
sys.path.append(mango_dir) 
import mango 

當然,您不需要mango_dir變量。

要理解它是如何工作的看着這個交互式會話例如:

>>> import os 
>>> mydir = '/home/me/application/app2/some_folder' 
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) 
>>> newdir 
    '/home/me/application/app2' 
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder' 
>>> 
>>> newdir 
'/home/me/application/app2/another_folder' 
>>> 

並檢查os.path文檔。

0

在我的情況下,我有一個類來導入。我的文件是這樣的:

# /opt/path/to/code/log_helper.py 
class LogHelper: 
    # stuff here 

在我的主文件I包括通過代碼:

path.append("/opt/path/to/code/") 
from log_helper import LogHelper 
0

嘗試Python的相對進口:

from ...app.folder.file import func_name 

每一個領導點是在另一個更高的層次從當前目錄開始的層次結構。


問題?如果這不適合你,那麼你可能正在被許多gotcha的相對進口所佔據。 閱讀答案和註釋瞭解更多詳情: How to fix "Attempted relative import in non-package" even with __init__.py

提示:有__init__.py在每一級目錄。您可能需要從頂級目錄運行的python -m application.app2.some_folder.some_file(離開.py)或在您的PYTHONPATH中具有該頂級目錄。 唷!

4

這裏的答案是缺乏透明度,這是關於Python 3.6

測試這個文件夾結構:

main.py 
| 
---- myfolder/myfile.py 

其中myfile.py有內容:

def myfunc(): 
    print('hello') 

main.py的進口報表是:

from myfolder.myfile import myfunc 
myfunc() 

,這將打印你好