我有一些代码分布在多个文件中,试图从彼此导入,如下所示:

main.py:

from entity import Ent

entity.py:

from physics import Physics
class Ent:
    ...

physics.py:

from entity import Ent
class Physics:
    ...

然后从main.py运行,得到以下错误:

Traceback (most recent call last):
File "main.py", line 2, in <module>
    from entity import Ent
File ".../entity.py", line 5, in <module>
    from physics import Physics
File ".../physics.py", line 2, in <module>
    from entity import Ent
ImportError: cannot import name Ent

我假设错误是由于导入实体两次-一次在main.py和物理。py -但我如何解决这个问题?


参见在Python中使用相互导入或循环(循环)导入时会发生什么?了解WRT循环导入所允许的内容以及导致问题的原因。参见为什么循环导入看起来在调用堆栈中更上一层,但随后在更下一层引发ImportError ?有关问题发生的原因和方式的技术细节。


当前回答

如前所述,这是由循环依赖关系引起的。没有提到的是,当你使用Python类型模块时,你导入一个类只用于注释类型,你可以使用Forward引用:

当类型提示包含尚未定义的名称时,则 定义可以表示为字符串字面量,稍后再解析。

并删除依赖项(导入),例如代替

from my_module import Tree

def func(arg: Tree):
    # code

do:

def func(arg: 'Tree'):
    # code

(注意删除的import语句)

其他回答

试试这个解决方案:重命名你的工作python脚本

你不应该用你导入的其他模块的名字来命名你当前的python脚本,因为你会得到这个错误。

例子:

您正在medicaltorch.py中工作 在这个脚本中,你有:from medicaltorch import X,其中medicaltorch应该是一个单独安装的模块

这将失败的ImportError,因为2件事涉及医疗火炬

因此,只需在1中重命名您的工作python脚本。

在我的例子中,只是错过了文件名:

from A.B.C import func_a (x)

from A.B.C.D import func_a (O)

其中D为file。

跟踪导入错误的一种方法是一步一步地尝试在每个导入的文件上运行python来跟踪坏的文件。

你会得到这样的结果: python。/ main.py ImportError:不能导入名称A 然后你启动: python。/模块/ a.py ImportError:不能导入名称B 然后你启动: python。/模块/ b.py ImportError:不能导入名称C(一些不存在的模块或其他错误)

如前所述,这是由循环依赖关系引起的。没有提到的是,当你使用Python类型模块时,你导入一个类只用于注释类型,你可以使用Forward引用:

当类型提示包含尚未定义的名称时,则 定义可以表示为字符串字面量,稍后再解析。

并删除依赖项(导入),例如代替

from my_module import Tree

def func(arg: Tree):
    # code

do:

def func(arg: 'Tree'):
    # code

(注意删除的import语句)

你有循环依赖的导入。在定义类Ent之前从实体导入physics.py,并且physics尝试导入已经初始化的实体。从实体模块中移除对物理的依赖。