当前位置: 首页 > 知识库问答 >
问题:

为什么在导入的模块中导入的工作方式不同?

尉迟鑫鹏
2023-03-14

如果我有的话

a.py
b.py

在< code>b.py中,我可以< code >导入a

但如果我有

c.py
m
  a.py
  b.py

在<code>c中。pydo导入m.b,突然出现在b中。py我得到ModuleNotFoundError:没有名为“a”的模块

怎么了?我看不出第二种情况与第一种情况有什么不同

因此...在最初启动的模块的目录中搜索模块。我只是不明白其中的道理。

我不是在问如何解决问题。而是首先问为什么会有问题......

(在Python 3.8.8上测试)

共有2个答案

宗政霄
2023-03-14

让我们从第一个为什么有效开始。假设您的文件结构如下:

c.py
m - |
    |
    __init__.py
    a.py
    b.py

假设您的当前目录位于 m 文件夹中,并且您运行该命令。

python b.py

如果在您的< code>b.py中放置了如下内容:

import a
import sys
print(sys.path)

它会很好地工作。但是,让我们看看print(sys.path)的输出。在windows上,这将类似于['C:\\path\\to\\myprogram\\m','

重要的是< code>m文件夹在您的< code>sys.path上,这就是< code>import a如何被解析的。

然而,如果我们向上一级运行:

python c.py

您应该立即注意到 M 不再在您的 sys.path 上,而是被替换为 'C:\\path\\to\\myprogram'

这就是它失败的原因。Python会自动将您当前的工作目录包含在sys.path中,改变它意味着它不再知道在哪里查找导入。

这是一个绝对进口的例子。通过修改< code>sys.path以包含您想要导入的文件的路径,您可以操纵python在哪里查找这些导入。

sys.path.append('C:\\path\\to\\myprogram\\m')

但是有一个更好的方法可以做到这一点。如果 m 是包或子包(包括__init__.py),则可以使用相对导入。

from . import a

然而,对此有一个小小的警告。当使用相对导入的文件作为模块或包运行时,只能使用相对导入。

所以直接作为顶层脚本运行它们

python b.py

会产生

ImportError: attempted relative import with no known parent package

幸运的是,Python能够将脚本作为内置模块运行。如果您将cd提升一级,以便封装m包,则可以运行

python -m m.b

让它正常运行。

此外,由于< code >导入,因此< code>b.py被视为< code>c.py中的一个模块,相对导入在这种情况下也将起作用。

python c.py
韩恺
2023-03-14

它基于你运行python的文件。

如果您使用pythonc.py运行

文件c.py使用:

从m导入a,b

文件b.py也使用:

从 m 导入 a

如果你去pythonb.py你只需要导入一个在b.py

因此,取决于您运行的文件,它将成为相对导入的父级。

 类似资料:
  • 问题内容: 我有一个使用内置模块的Python脚本,但也导入了与主脚本本身位于同一目录中的许多自定义模块。 例如,我会打电话 和agent.py具有许多导入,包括: 其中checks与agent.py位于同一目录中的文件 当前工作目录为agent /时,一切都很好。但是,如果我从任何其他目录调用agent.py,则显然无法导入checks.py等错误。 我如何确保可以导入自定义模块,而不管从哪里调

  • 问题内容: 谁能建议我在python中导入模块的最pythonic方法是什么?让我解释一下- 我已经阅读了很多python代码,并发现了几种不同的方式来导入模块,或者更确切地说,是何时导入: 使用一个模块/几个模块,其中包括整个项目所需的所有导入(第三方模块),因此所有导入都集中在几个模块中,因此易于维护导入。当任何单个模块需要导入任何模块时,都会询问引用模块。例如,在我们的项目中,我们分离了名为

  • 问题内容: 我注意到我今天想解释的东西很奇怪。我不是100%不确定如何将其表达为一个问题,所以google是不可能的。由于某些奇怪的原因,日志记录模块无权访问模块logging.handlers。如果您不相信我,请自己尝试: 谁能解释为什么会这样? 问题答案: 在Python中,需要先导入模块,然后才能对其进行访问。仅导入日志记录模块。碰巧这是一个带有子模块的软件包,但是那些子模块仍然不会自动加载

  • 主要内容:导入模块方式一:临时添加模块完整路径,导入模块方式二:将模块保存到指定位置,导入模块方式三:设置环境变量很多初学者经常遇到这样的问题,即自定义 Python 模板后,在其它文件中用 import(或 from...import) 语句引入该文件时,Python 解释器同时如下错误: ModuleNotFoundError: No module named '模块名' 意思是 Python 找不到这个模块名,这是什么原因导致的呢?要想解决这个问题,读者要先搞清楚 Python 解释器查找

  • 根据这个答案,您可以使用来使用类似这样的相对导入: 为什么相对导入不适用于sklearn。特征提取。文本 我验证了是一个具有以下功能的模块: 编辑 “不工作”,我的意思是它不导入模块。 我正在使用Python 3.4 绝对方式工作: 相对方式不:

  • 我需要在Python中导入一个名为array_queue的模块。我检查了一下,如果我不使用它,就会出现一个提示:“array_queue imported but unused”。但是,如果我使用它并运行该程序,则会出现以下情况: ModuleNotFounderRror:没有名为“array_queue”的模块