Python - 导入错误

2 投票
3 回答
528 浏览
提问于 2025-04-15 21:39

我做了一件不该做的事,写了4个模块(大约花了6个小时),但在这个过程中没有运行任何测试。

我在 /mydir/__init__.py 里有一个叫 get_hash() 的方法,在 /mydir/utils.py 里有一个叫 SpamClass 的类。

/mydir/utils.py/mydir/__init__ 导入了 get_hash()

/mydir/__init__.py 又从 /mydir/utils.py 导入了 SpamClass

这两个类和方法单独运行都没问题,但不知为什么,当我尝试导入 /mydir/ 时,出现了一个导入错误,提示 "无法从 /mydir/__init__.py 导入名称 get_hash"

唯一的错误追踪信息是说 __init__.py 导入了 SpamClass。接下来出错的地方是在 SpamClass 中尝试导入 get_hash 的时候。为什么会这样呢?

3 个回答

1

在没有更多信息的情况下,我可以说你遇到了一个循环导入的问题,而你没有找到解决办法。最简单、最明显的解决方法就是不要在 mydir/__init__.py 文件里放任何你想在 mydir 目录下的其他模块中使用的东西。所以,把你的 get_hash 函数移动到 mydir 包里的另一个模块中,然后在需要的地方导入那个模块。

2

补充一下其他人说的内容,避免循环导入问题的一个好方法就是避免使用 from module import stuff 这种写法。

如果你在每个脚本的开头都用标准的 import module,然后在你的函数里写 module.stuff,那么等到这些函数运行的时候,模块的导入已经完成了,所有的模块成员都会可用。

这样你也不用担心某些模块会更新或改变它们的成员(或者被调皮的第三方修改)。如果你用了 from 导入模块,你可能还会拿到一个过时的成员副本。

就我个人而言,我只在一些简单、不依赖其他东西的成员上使用 from-import,特别是一些符号常量,因为我可能会经常用到它们。

2

这个问题其实很常见。发生的情况是,解释器会逐行执行你的 __init__.py 文件。当你有以下代码时:

 import mydir.utils
 def get_hash(): return 1

解释器会在 import mydir.utils 这一行暂停处理 __init__.py,直到它完全执行完 'mydir/utils.py'。所以当 utils.py 尝试导入 get_hash() 时,它并没有被定义,因为解释器还没有执行到它的定义那一行。

撰写回答