【问题标题】:Why importing in the imported modules works differently?为什么在导入的模块中导入的工作方式不同?
【发布时间】:2021-08-30 09:12:23
【问题描述】:

如果我有

a.py
b.py

b.py 我可以import a

如果我有

c.py
m
  a.py
  b.py

然后在c.pyimport m.b,突然在b.py 我得到ModuleNotFoundError: No module named 'a'

有什么问题?我看不出第二种情况与第一种情况有何不同

所以...在最初启动的模块的目录中搜索模块。我只是不明白其中的原因。

我不是在问如何解决这个问题。而是先问为什么会出现问题……

(在 Python 3.8.8 上测试)

【问题讨论】:

  • 这能回答你的问题吗? Import a file from a subdirectory?
  • 顺便说一句,我发现在开发多模块包时处理此类问题的最佳方法是以可编辑模式安装项目 - 请参阅stackoverflow.com/questions/35064426/…。然后所有的导入语句将从同一个源根目录开始。
  • @warvariuc 在没有明确指定它是相对路径的情况下,它没有回答为什么它不起作用。然而,当所有模块都在同一个目录中时它可以工作
  • @Hrisip。您有模块a 的绝对路径,因此,您的脚本在顶层的根目录中需要模块a。您可以通过像这样导入 a 来修复它:import m.afrom . import a

标签: python python-3.x


【解决方案1】:

这取决于你运行 python 的文件。

如果您使用python c.py 运行

文件 c.py 使用:

from m import a, b

文件 b.py 也使用:

from m import a

如果你去python b.py,你只需要import a 在 b.py 中使用

所以取决于你运行的文件是相对导入的父文件。

【讨论】:

    【解决方案2】:

    让我们从第一个有效的原因开始。 假设你的文件结构是这样的:

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

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

    python b.py
    

    如果在您的 b.py 中放置类似以下内容:

    import a
    import sys
    print(sys.path)
    

    它会工作得很好。但是让我们看一下print(sys.path) 的输出。 在 Windows 上,这看起来像 ['C:\\path\\to\\myprogram\\m', '<path to python installation>', etc.]

    重要的是m 文件夹在您的sys.path 上,这就是import a 得到解决的方式。

    但是,如果我们上一层并运行:

    python c.py
    

    您应该立即注意到m 不再出现在您的sys.path 上,而是被'C:\\path\\to\\myprogram' 取代。

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

    这是一个绝对导入的例子。您可以通过修改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
    

    让它运行得很好。

    此外,由于b.pyc.py 中的模块视为import,因此在这种情况下相对导入也将起作用。

    python c.py
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多