我编写了一系列python模块,这些模块保存在同一目录中,我遇到了一个ImportError问题。
我使用的三个模块是draw_menu.py
,errors.py
和file_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
的情况下解决这个问题?
谢谢你
汤姆
答案 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)
这样,您只会在常规导入运行后导入错误。