一种方法是使用import x,而不使用“from”关键字。那么你可以在任何地方用名称空间来引用它们。在Python中避免循环(循环)导入?
有没有其他办法?像在C++中做的事情ifnotdef __b__ def __b__类型的东西?
一种方法是使用import x,而不使用“from”关键字。那么你可以在任何地方用名称空间来引用它们。在Python中避免循环(循环)导入?
有没有其他办法?像在C++中做的事情ifnotdef __b__ def __b__类型的东西?
将任何一对互相依赖的模块合并到一个模块中。然后引入额外的模块以恢复旧名称。
例如,
# a.py
from b import B
class A: whatever
# b.py
from a import A
class B: whatever
成为
# common.py
class A: whatever
class B: whatever
# a.py
from common import A
# b.py
from common import B
圆形进口是一个 “代码味道”,和经常(但不总是)表明一些重构将是适当的。例如,如果A.x
使用B.y
和B.y
使用A.z
,那么你可以考虑将A.z
移动到它自己的模块中。
如果您认为需要循环导入,那么我通常会建议导入模块并引用具有完全限定名称的对象(即import A
和使用A.x
而不是from A import x
)。
如果你正在进行一些明确的类型检查,该怎么办?我现在正在尝试这样做,所以我可以提供非常详细的错误消息,而不是我的客户不理解的一些令人迷惑的追踪。 – Nick
如果您想要做from A import *
,答案很简单:不要这样做。你通常假设做import A
并引用限定名称。
对于快速&脏脚本和交互式会话,这是一件非常合理的事情 - 但在这种情况下,您将不会遇到循环导入。
在某些情况下,在实际代码中执行import *
是有意义的。例如,如果你想隐藏一个复杂的模块结构,或者动态生成的模块结构,或者在不同版本间频繁变化,或者你要包装的嵌套层次太深的其他软件包,import *
可能从“包装器模块“或顶级封装模块。但在这种情况下,您导入的任何东西都不会导入您。
事实上,我很难想象任何情况下import *
是保证和循环依赖甚至是可能性。
如果你在做from A import foo
,那么有办法(例如,import A
然后foo = A.foo
)。但你可能不想这样做。再次考虑您是否真的需要将foo
加入您的名称空间 - 限定名称是一项功能,而不是需要解决的问题。
如果你正在做的只是from A import foo
为了方便实现你的功能,因为A
实际上是long_package_name.really_long_module_name
和你的代码是因为所有这些调用long_package_name.really_long_module_name.long_class_name.class_method_that_puts_me_over_80_characters
的不可读,请记住,你总是可以import long_package_name.really_long_module_name as P
,然后使用P
你合格调用。
(另外请记住,与实施方便做任何from
,你可能希望确保指定__all__
以确保进口的名字不,如果有人对你做一个import *
似乎是你的命名空间的一部分来自互动式会议。)
另外,正如其他人指出的那样,大多数(但不是全部)循环依赖的情况是设计不良的一个症状,并且以合理的方式重构模块将会修复它。在极少数情况下,您确实需要将名称带入名称空间,并且一组循环的模块实际上是最好的设计,但某些人工重构可能仍然是比foo = A.foo
更好的选择。
没有循环依赖关系,通过组合y的x和y的依赖关系来创建z – Esailija
这篇文章是重复的:http://stackoverflow.com/questions/744373/circular-or-cyclic -imports-in-python – alinsoar
@alinsoar这不是一个完全重复的问题 - 当你有循环导入时会发生什么?这个问题要求技术来避免它们。 –