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

时间:2010-07-13 09:14:55

标签: python import importerror

我编写了一系列python模块,这些模块保存在同一目录中,我遇到了一个ImportError问题。

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

errors.py我需要一个错误代码列表,我使用file_operations.py中定义的自定义方法打开一个包含代码的文件,因此我在她下面使用import file_operations -bang(在课程定义之上)。

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

以上一直运行正常但是当我使用draw_menu.py使用文件来定义ascii菜单中的选项时(因此我使用import file_operations)遇到了ImportError。

ImportError: cannot import name file_operations

据我所知,这是因为'import tree'如果你喜欢的流程如下:

draw_menu< - file_operations< - errors< - file_operations

重要的是每个模块都可以单独使用,为什么这是一个问题,如何在不从import file_operations移除errors.py的情况下解决这个问题?

谢谢你

汤姆

3 个答案:

答案 0 :(得分:2)

循环导入可能会导致Python出现问题(正如您所料)。值得检查的是:

A)errors.py和file_operation.py应该是单个模块(如果它们都相互依赖,它们是否需要分开?)

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

答案 1 :(得分:1)

问题不在于导入本身,而是依赖项。在file_operations导入errors之前,无法处理errors,但在导入file_operations之前无法处理{{1}}。 Python认为这是一种不可能的情况,并引发错误。

对此最好的解决方案是重构您的文件,以便您不再具有此循环依赖性。如果真的不可能,替代解决方案是更改其中一个模块,以便在需要它的函数内部而不是在顶层执行违规导入。这意味着模块的初始处理不依赖于导入,因此它将成功。

答案 2 :(得分:0)

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

问题是导入(作为副作用)实际上会运行导入的模块(第一次调用导入时)。因此,如果您要导入一个导入原始模块的模块,那么事情会变得混乱。

您可能会发现只需在实际需要使用它时导入errors / file_operations即可解决问题。这可能在一个函数内。因此可能将调用函数包装错误:


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

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