【问题标题】:Import Error on trying to import a submodule that imports a submodule尝试导入导入子模块的子模块时出现导入错误
【发布时间】:2016-03-23 23:38:08
【问题描述】:

我觉得我缺少一些简单而基本的东西。这是一个玩具设置

PythonProject/
main.py
x/
    a.py
    y/
        b.py

b.py 有一个没有依赖关系的函数 foo

def foo():
    print("Hello World")

a.py 需要 b.py 中的 foo 才能工作并直接导入它

import y.b
def bar():
    #Do some stuff
    y.b.foo()

main.py 需要来自 a.py 的 bar

import x.a
x.a.bar()

现在,运行 a.py 工作正常,它成功导入 b 并找到 foo。 尝试运行 main.py 但是会因导入错误而中断:特别是“import b”在“import a”期间失败

我的印象是,需要发生的事情是 b 需要在 a/ 中通过 __init__.py 公开,但我不确定这样做的 Pythonic 方式是什么。

导入一个模块 (a) 的首选解决方案是什么

【问题讨论】:

  • 我逐字复制了您的代码,问题无法重现。您收到的确切错误是什么?我们可以看到更多代码吗?
  • 感谢您的回复!我编辑了示例中的代码,使目录名与文件名不同。当我运行我现在发布的确切代码时,我得到:Traceback (most recent call last): File "main.py", line 1, in <module> import x.a File "/Users/rsmirol/PythonProject/x/a.py", line 1, in <module> import y.b ImportError: No module named 'y'
  • 这发生在python3 main.py
  • 好的,我现在试试。
  • 我找到了解决办法!我会把它作为答案发布。

标签: python python-import


【解决方案1】:

尽管 Paul H 提到了答案,但从未正确回答。

很简单,提到但没有直接说here

如果你有这样的目录:

sound/                      Top-level package
  __init__.py               Initialize the sound package
  formats/                  Subpackage for file format conversions
          __init__.py
          wavread.py
          wavwrite.py
          aiffread.py
          aiffwrite.py
          auread.py
          auwrite.py
          ...
  effects/                  Subpackage for sound effects
          __init__.py
          echo.py
          surround.py
          reverse.py
          ...
  filters/                  Subpackage for filters
          __init__.py
          equalizer.py
          vocoder.py
          karaoke.py
          ...

(例如“效果”)中的__init__.py文件需要包含

import effects.echo
import effects.surround
import effects.reverse

要从子模块中调用子模块,例如,echo 调用环绕声,那么您需要使用以下命令将环绕声导入 echo import effects.surround as surround

【讨论】:

  • 虽然 - 如果有人想添加这个,以便 echo 中的 main() 函数不需要调用 echo.main(arg1, etc) 而是 echo(arg1, etc)那太好了
【解决方案2】:

来自Importing files from different folder in Python

main.py

​​>
import sys
sys.path.insert(0, 'C:/path/x')
import a
a.bar()

a.py

​​>
import sys
sys.path.insert(0, 'C:/path/x/y')
import b
def bar():
    #Do some stuff
    b.foo()

b.py

​​>
def foo():
    print("Hello World")

【讨论】:

  • 所以概括地说,我们可以让操作系统找到模块的绝对路径并将其添加到 python 路径中吗?您认为在 __init__.py 中对模块执行此操作是否有意义?
  • @Zaez 不要弄乱路径。使用__init__.py 文件。 stackoverflow.com/a/21995949/1552748
  • @PaulH 我没有看到一个解决方案可以在不直接或__init__.py 文件中弄乱路径的情况下工作。我错过了什么?问题本质上是项目根不关心y,而是关心关心y的x,所以当x调用`import y.b'时,会出现找不到y的导入错误。
  • 每个目录都需要一个初始化文件。每个初始化文件都应该导入它想要向用户公开的函数。无需修改路径。
  • 这不是构建包的方式:docs.python.org/3/tutorial/modules.html#packages
猜你喜欢
  • 2020-10-25
  • 2021-10-24
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 2010-11-16
  • 2012-08-27
  • 1970-01-01
相关资源
最近更新 更多