繁体   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