我有四个不同的文件,分别命名为:main.py
、vector.py
、entity.py
和 physics.py
。我不会发布所有代码,只发布导入,因为我认为这就是错误所在(如果你愿意,我可以发布更多)。
主要.py:
import time
from entity import Ent
from vector import Vect
#the rest just creates an entity and prints the result of movement
实体.py:
from vector import Vect
from physics import Physics
class Ent:
#holds vector information and id
def tick(self, dt):
#this is where physics changes the velocity and position vectors
矢量.py:
from math import *
class Vect:
#holds i, j, k, and does vector math
物理.py:
from entity import Ent
class Physics:
#physics class gets an entity and does physics calculations on it.
然后我从 main.py
运行,我收到以下错误:
回溯(最后一次调用):文件“main.py”,第 2 行,在
我猜该错误是由于两次导入实体造成的,一次在 main.py
中,然后在 physics.py
中,但我不知道解决方法。任何人都可以帮忙吗?
from <module> import <name>
或 from <modlue> import *
不是好的编码习惯。最好在模块命名空间下导入,以防止覆盖同名引用的机会。
Entity
和 Vector
而不是 Ent
和 Vect
,没有理由缩短这些名称。是的,使用 import vector
,然后使用 x = vector.Vector(0,0,0)
。
您有循环依赖导入。 physics.py
在定义类 Ent
之前从 entity
导入,physics
尝试导入已经初始化的 entity
。从 entity
模块中删除对 physics
的依赖关系。
虽然您绝对应该避免循环依赖,但您可以在 python 中延迟导入。
例如:
import SomeModule
def someFunction(arg):
from some.dependency import DependentClass
这(至少在某些情况下)将规避错误。
这是一个循环依赖。它可以在不对代码进行任何结构修改的情况下解决。出现问题是因为在 vector
中您要求 entity
立即可用,反之亦然。这个问题的原因是您要求在模块准备好之前访问它的内容——通过使用 from x import y
。这本质上是一样的
import x
y = x.y
del x
Python 能够检测循环依赖并防止导入的无限循环。基本上所有发生的事情是为模块创建了一个空占位符(即它没有内容)。一旦循环依赖的模块被编译,它就会更新导入的模块。这是这样的。
a = module() # import a
# rest of module
a.update_contents(real_a)
要使 python 能够处理循环依赖项,您必须仅使用 import x
样式。
import x
class cls:
def __init__(self):
self.y = x.y
由于您不再引用顶层模块的内容,python 可以编译模块而无需实际访问循环依赖项的内容。顶层是指将在编译期间执行的行,而不是函数的内容(例如y = x.y
)。访问模块内容的静态或类变量也会导致问题。
import app.foo.bar
),则需要为其命名(即 import app.foo.bar as bar
)
就我而言,我在 Jupyter 笔记本中工作,这是因为当我在工作文件中定义类/函数时,导入已经被缓存。
我重新启动了 Jupyter 内核,错误消失了。
使逻辑清晰非常重要。出现这个问题,是因为引用变成了死循环。
如果你不想改变逻辑,你可以把一些导致 ImportError 的 import 语句放到文件的其他位置,例如结尾。
一个.py
from test.b import b2
def a1():
print('a1')
b2()
b.py
from test.a import a1
def b1():
print('b1')
a1()
def b2():
print('b2')
if __name__ == '__main__':
b1()
您将收到 Import Error: ImportError: cannot import name 'a1'
但是如果我们改变 A 中 from test.b import b2 的位置,如下所示:
一个.py
def a1():
print('a1')
b2()
from test.b import b2
我们可以得到我们想要的:
b1
a1
b2
这是一个循环依赖。我们可以通过在需要的地方使用导入模块或类或函数来解决这个问题。如果我们使用这种方法,我们可以修复循环依赖
py
from B import b2
def a1():
print('a1')
b2()
py
def b1():
from A import a1
print('b1')
a1()
def b2():
print('b2')
if __name__ == '__main__':
b1()
我也遇到了这个错误,原因不同...
from my_sub_module import my_function
主脚本有 Windows 行尾。 my_sub_module
具有 UNIX 行结尾。将它们更改为相同可以解决问题。它们还需要具有相同的字符编码。
问题很明显:entity
和 physics
模块中的名称之间存在循环依赖。
无论导入整个模块还是仅导入一个类,都必须加载名称。
看这个例子:
# a.py
import b
def foo():
pass
b.bar()
# b.py
import a
def bar():
pass
a.foo()
这将被编译成:
# a.py
# import b
# b.py
# import a # ignored, already importing
def bar():
pass
a.foo()
# name a.foo is not defined!!!
# import b done!
def foo():
pass
b.bar()
# done!
稍作改动,我们就可以解决这个问题:
# a.py
def foo():
pass
import b
b.bar()
# b.py
def bar():
pass
import a
a.foo()
这将被编译成:
# a.py
def foo():
pass
# import b
# b.py
def bar():
pass
# import a # ignored, already importing
a.foo()
# import b done!
b.bar()
# done!
如前所述,这是由循环依赖引起的。没有提到的是,当您使用 Python typing 模块并导入一个仅用于注释 Types 的类时,您可以使用 Forward references:
当类型提示包含尚未定义的名称时,该定义可以表示为字符串文字,稍后再解析。
并删除依赖项(导入),例如,而不是
from my_module import Tree
def func(arg: Tree):
# code
做:
def func(arg: 'Tree'):
# code
(注意删除的 import
语句)
试试这个解决方案:重命名你的工作 python 脚本
你不应该用你导入的其他模块的名字来命名你当前的 python 脚本,因为你会得到那个错误。
例子:
你在那个脚本中的 medicaltorch.py 中工作,你有: from medicaltorch import X where medicaltorch 应该是一个单独的安装模块
这将因 ImportError
而失败,因为有 2 件事涉及 medicaltorch
因此,只需将您的工作 python 脚本重命名为 1。
如果您从 file2.py
导入 file1.py
并使用了这个:
if __name__ == '__main__':
# etc
低于 file1.py
无法导入到 file2.py
中的变量,因为 __name__
不等于 __main__
!
如果您想将某些内容从 file1.py
导入到 file2.py
,您需要在 file1.py
中使用它:
if __name__ == 'file1':
# etc
如有疑问,请作出 assert
声明以确定是否 __name__=='__main__'
跟踪导入错误的一种方法是逐步尝试在每个导入的文件上运行 python 以跟踪错误的文件。
你会得到类似的东西: python ./main.py ImportError: cannot import name A then you launch: python ./modules/a.py ImportError: cannot import name B then you launch: python ./modules/b.py ImportError: cannot导入名称 C(一些不存在的模块或其他一些错误)
也与 OP 没有直接关系,但是在将新对象添加到模块后未能重新启动 PyCharm Python 控制台,这也是获得非常混乱的ImportError: Cannot import name ...
的好方法
令人困惑的部分是 PyCharm 会在控制台中自动完成导入,但导入会失败。
还没有在这里看到这个 - 这非常愚蠢,但请确保您正在导入正确的变量/函数。
我收到了这个错误
ImportError:无法导入名称 IMPLICIT_WAIT
因为我的变量实际上是 IMPLICIT_TIMEOUT
。
当我将导入更改为使用正确的名称时,我不再收到错误🤦♂️
from PIL import Pillow
不起作用的人。 😠
不是专门针对这个提问者,但是如果您导入的类名与您从中导入的文件中的定义不匹配,则会显示相同的错误。
就我而言,只是错过了文件名:
从 ABC 进口 func_a (x)
从 ABCD 导入 func_a (O)
其中 D 是文件。
Entity
和Physics
究竟如何(就代码而言)相互关联?我确定您正在尝试做的事情有一种解决方法。