簡體   English   中英

跨包導入模塊時,Python“ ImportError:未命名模塊”

[英]Python 'ImportError: No module named' when importing modules across packages

嘗試從駐留在另一個Python包中的模塊導入一個駐留在另一個Python包中的Python模塊時,遇到了一個Python“ ImportError:No module named ...”錯誤。 下圖顯示了目錄結構:

通過PyCharm的項目目錄結構

必須注意的是,僅當我從終端運行腳本時才出現此錯誤,而通過PyCharm執行時,此腳本成功運行。 從終端執行時的錯誤如下:

Traceback (most recent call last):
File "social_networks/linked_data.py", line 15, in <module>
    from text_analysis.text_refinement import camel_case_split
ImportError: No module named 'text_analysis'

我嘗試了以下不同的導入方式,但均未成功:

方法1:

sys.path.insert(0, os.path.realpath('../text_analysis'))
from text_analysis.text_refinement import camel_case_split

方法2:

from text_analysis.text_refinement import camel_case_split

這個問題有什么解決方案?

簡潔版本

更改為:

sys.path.insert(0, os.path.realpath('./'))
from text_analysis.text_refinement import camel_case_split

要么:

sys.path.insert(0, os.path.realpath('./text_analysis'))
from text_refinement import camel_case_split

長版

我已經在計算機上重新創建了您的項目結構,並設法使其正常工作。 讓我們一步一步走,以便我們找出正在發生的事情。

首先,我看到您正在使用PyCharm進行項目。 它會自動將項目根目錄添加到PYTHONPATH 您可以在此線程中詳細了解此內容。 由於PyCharm會為您處理路徑業務,因此您實際上並不需要

sys.path.insert(0, os.path.realpath('../text_analysis'))

讓您的代碼運行。 該路徑仍將添加,但不會用於定位軟件包。 在您的機器上嘗試一下。 我認為您會發現它是真實的。 您可以通過運行輕松檢查路徑

for path in sys.path:
    print(path)

盡管這是有趣的信息,但它不能回答您如何從終端運行它的問題。 要了解為什么不能從腳本中運行它,請看一下在方法1中執行(略微修改)命令后將擁有哪些Python路徑:

sys.path.insert(0, os.path.realpath('../text_analysis'))

try:
    from text_analysis.text_refinement import camel_case_split
    camel_case_split()
except:
    for path in sys.path:
        print(path)

# output:
# ~/text_analysis (where ../text_analysis path points to)
# ~/social-network-interest-engine/social_networks (where your file is)
# ... (several other irrelevant paths) ...

我們可以看到'../text_analysis'指向您所需目錄上方的一個目錄。 如果我們刪除'./text_analysis'之一,而寫了'./text_analysis' ,將會發生什么? 輸出似乎是我們需要的:

# output:
# ~/social-network-interest-engine/text_analysis
# ~/social-network-interest-engine/social_networks

但是我們仍然沒有導入功能。 我們知道這一點是因為我們到達了except部分,該部分打印了路徑。 查看import,我們可以看到我們有text_analysis.text_refinement 如果我們已經將目錄名稱添加到路徑中,是否真的需要聲明目錄名稱? 不我們沒有。 如果我們寫

from text_refinement import camel_case_split

相反,我們發現該函數終於被導入了。 遵循此邏輯,並假設我們想將import語句中的text_analysis.text_refinement保留(無論出於何種原因),我們也可以不同地添加路徑:

sys.path.insert(0, os.path.realpath('./'))

但是請注意,這種插入路徑的方法有些脆弱。 起始位置是您調用python python_file.py的路徑。如果導航到其他目錄,則需要相應地調整os.path.realpath 您可以做什么:

sys.path.insert(0, 'full/path/to/application/app/folder')

盡管這假定項目的目錄/結構不會更改。

有關路徑和導入的更深入概述,您可以在此處閱讀有關從不同文件夾中導入內容的更多信息,如果您喜歡相對路徑導入, 是一個有用的線程。 當然, 正式文檔也是一個不錯的起點。

暫無
暫無

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

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