Python循环导入?
所以我得到了这个错误Python循环导入?,python,import,circular-dependency,Python,Import,Circular Dependency,所以我得到了这个错误 Traceback (most recent call last): File "/Users/alex/dev/runswift/utils/sim2014/simulator.py", line 3, in <module> from world import World File "/Users/alex/dev/runswift/utils/sim2014/world.py", line 2, in
Traceback (most recent call last):
File "/Users/alex/dev/runswift/utils/sim2014/simulator.py", line 3, in <module>
from world import World
File "/Users/alex/dev/runswift/utils/sim2014/world.py", line 2, in <module>
from entities.field import Field
File "/Users/alex/dev/runswift/utils/sim2014/entities/field.py", line 2, in <module>
from entities.goal import Goal
File "/Users/alex/dev/runswift/utils/sim2014/entities/goal.py", line 2, in <module>
from entities.post import Post
File "/Users/alex/dev/runswift/utils/sim2014/entities/post.py", line 4, in <module>
from physics import PostBody
File "/Users/alex/dev/runswift/utils/sim2014/physics.py", line 21, in <module>
from entities.post import Post
ImportError: cannot import name Post
回溯(最近一次呼叫最后一次):
文件“/Users/alex/dev/runswift/utils/sim2014/simulator.py”,第3行,在
从世界进口世界
文件“/Users/alex/dev/runswift/utils/sim2014/world.py”,第2行,在
从entities.field导入字段
文件“/Users/alex/dev/runswift/utils/sim2014/entities/field.py”,第2行,在
从entities.goal导入目标
文件“/Users/alex/dev/runswift/utils/sim2014/entities/goal.py”,第2行,在
from entities.post导入post
文件“/Users/alex/dev/runswift/utils/sim2014/entities/post.py”,第4行,在
从物理学导入后体
文件“/Users/alex/dev/runswift/utils/sim2014/physics.py”,第21行,在
from entities.post导入post
ImportError:无法导入姓名栏
你可以看到,我进一步使用了相同的import语句,它可以工作吗?关于循环导入是否有一些不成文的规定?如何进一步使用调用堆栈中的同一类?当您第一次导入模块(或其成员)时,模块内的代码会像任何其他代码一样按顺序执行;e、 例如,对函数体的处理没有任何不同。import
与其他命令一样,只是一个命令(赋值、函数调用、def
、class
)。假设您的导入发生在脚本的顶部,那么下面是发生的情况:
- 当您尝试从
导入World
时,将执行World
脚本World
脚本导入world
,从而执行字段
脚本实体.Field
- 此过程将继续,直到您到达
脚本,因为您尝试导入实体.post
post
脚本导致执行entities.post
模块,因为它试图导入physics
PostBody
- 最后,
尝试从physics
实体导入
。PostPost
- 我不确定
模块是否存在于内存中,但这并不重要。模块不在内存中,或者模块没有entities.post
成员,因为它尚未完成定义Post
Post
- 无论哪种方式,都会发生错误,因为不存在要导入的
Post
Post
时出错。你不应该使用循环导入。充其量,它的好处可以忽略不计(通常,没有好处),并且它会导致类似这样的问题。它给任何维护它的开发者带来负担,迫使他们在蛋壳上行走以避免打破蛋壳。重构您的模块组织。当您第一次导入模块(或其成员)时,模块内的代码会像任何其他代码一样按顺序执行;e、 例如,对函数体的处理没有任何不同。import
与其他命令一样,只是一个命令(赋值、函数调用、def
、class
)。假设您的导入发生在脚本的顶部,那么下面是发生的情况:
- 当您尝试从
导入World
时,将执行World
脚本World
脚本导入world
,从而执行字段
脚本实体.Field
- 此过程将继续,直到您到达
脚本,因为您尝试导入实体.post
post
脚本导致执行entities.post
模块,因为它试图导入physics
PostBody
- 最后,
尝试从physics
实体导入
。PostPost
- 我不确定
模块是否存在于内存中,但这并不重要。模块不在内存中,或者模块没有entities.post
成员,因为它尚未完成定义Post
Post
- 无论哪种方式,都会发生错误,因为不存在要导入的
Post
Post
时出错。你不应该使用循环导入。充其量,它的好处可以忽略不计(通常,没有好处),并且它会导致类似这样的问题。它给任何维护它的开发者带来负担,迫使他们在蛋壳上行走以避免打破蛋壳。重构您的模块组织。我认为,虽然这一点都没有错,但循环导入的影响太大了。如果设置正确,它们可以正常工作
最简单的方法是使用导入我的\u模块
语法,而不是从我的\u模块导入一些\u对象。前者几乎总是有效的,即使所包含的myu模块
将我们重新导入。只有在my_模块
中已经定义了my_对象
时,后者才起作用,而在循环导入中可能不是这样
针对您的具体情况:尝试更改实体/post.py
以执行导入物理
,然后直接参考物理.PostBody
,而不仅仅是PostBody
。类似地,将physics.py
改为导入实体.post
,然后使用实体.post.post
,而不仅仅是post
,,我认为,虽然这并不是错的,但是循环导入的成本太高了。如果设置正确,它们可以正常工作
最简单的方法是使用导入我的\u模块
语法,而不是从我的\u模块导入一些\u对象。前者几乎总是有效的,
class Car(models.Model):
manufacturer = models.ForeignKey(
'production.Manufacturer',
on_delete=models.CASCADE,
)
def X1:
return "x1"
from Y import Y2
def X2:
return "x2"
def Y1:
return "y1"
from X import X1
def Y2:
return "y2"
from X import Y
import X
z = X.Y
#import X (actual import moved down to avoid circular dependency)
from module import Foo
foo_instance = Foo()
import module.foo
foo_instance = foo.Foo()
def my_func():
import Foo
foo_instance = Foo()