当我尝试'重新导入'模块时,为什么会遇到ImportError?

问题描述:

我有一系列python模块写在同一个目录下,我遇到了ImportError问题。当我尝试'重新导入'模块时,为什么会遇到ImportError?

我使用的三个模块是draw_menu.py,errors.pyfile_operations.py

errors.py我需要的错误代码的列表,我使用在file_operations.py定义的自定义方法以打开包含代码因此我使用import file_operations只是她爆炸的下方(在类定义如上)的文件。

file_operations.py我使用error.py中定义的方法在出错时打印错误消息(例如找不到文件等)。因此我在这里采用相同的方式import errors

上述工作正常,但当我使用draw_menu.py,它使用文件来定义ascii菜单中的选项(因此我使用import file_operations)时遇到了一个ImportError。

ImportError: cannot import name file_operations

我明白,这是因为 '进口树' 如果你喜欢流向如下:

draw_menu < - file_operations < - errors < - file_operations

这是每个重要模块可以单独使用,为什么这是一个问题,我怎样才能克服这一点,而不需要从errors.py删除import file_operations

三江源

汤姆

圆形进口可能在Python引起的问题(如你所期望的)。这也许值得一试,如果:?

A)errors.py和file_operation.py应该是单个模块(如果他们都如此依赖对方,做他们需要的是独立的)

B)你可以在一个或另一个模块中延迟import。在函数调用之前,函数中的导入语句不会运行,虽然在模块的开头导入通常是很好的做法,但在Python中不需要。在这种情况下,它可以避免导入期间的循环引用。

+0

感谢您的快速回复,我保留了两个模块,并将'import file_operations'移入'errors.py'中定义的所需方法内,这解决了我的问题。通常从循环导入中会产生什么样的问题? – Thorsley 2010-07-13 09:29:36

+0

@Thorsley:http://*.com/questions/3082015/python-module-initialization-order/3082097#3082097 – 2010-07-13 09:31:16

+0

在http://effbot.org/zone/上有一篇关于python导入的旧文章,但非常好。 import-confusion.htm和关于循环进口的章节。值得一读。 – mavnn 2010-07-13 09:31:30

问题不是进口本身,而是依赖关系file_operations只有在导入errors后才能被处理,但errors只有在导入了file_operations之后才能被处理。 Python认识到这是一种不可能的情况,并产生错误。

对此的最佳解决方案是重构您的文件,以便您不再需要此循环依赖项。如果这是不可能的,另一种解决方案是更改其中一个模块,以便在需要它的函数内发生违规导入,而不是在顶层。这意味着模块的初始处理不依赖于导入,因此它会成功。

+0

这是不正确的。其他模块中的引用不能*使用*直到导入过程完成足够远以便定义它们,而仅仅导入模块不是问题。 – 2010-07-13 09:27:37

除了打破循环依赖,您可以尝试移动导入调用的位置。不要忘记,Python中的导入只是常规语句,因此您可以导入内部函数。

问题是导入(作为副作用)将实际运行正在导入的模块(第一次调用导入时)。所以,如果你正在导入一个导入原始模块的模块,那么你会感到困惑。

您可能会发现,只需在实际需要使用它的位置导入错误/ file_operations即可缓解此问题。这可能在一个函数中。因此,也许将错误的调用包含到函数中:

 

def print_error_message(err): 
    from errors import print_error_message as _print_error_message 
    _print_error_message(err) 
 

这样,您只会在正常导入运行后导入错误。

+0

或者你可以只在顶部输入错误,并在函数内部使用'errors.print_error_message'。 – 2010-07-13 09:30:02