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

发布于 2024-09-09 09:18:48 字数 936 浏览 11 评论 0原文

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

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

errors.py 中,我需要一个错误代码列表,我正在使用 file_operations.py 中定义的自定义方法来打开包含代码的文件,因此我使用 import file_operations 位于 she-bang 下方(类定义上方)。

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

上面的代码运行良好,但是当我使用 draw_menu.py 时,它使用一个文件来定义 ascii 菜单中的选项(因此我使用 import file_operations)遇到导入错误。

ImportError:无法导入名称 file_operations

我知道这是因为“导入树”(如果您喜欢如下流程):

draw_menu - file_operations errors file_operations

重要的是每个模块都可以单独使用,为什么这是一个问题以及如何在不删除 import 的情况下克服这个问题来自 errors.py 的 file_operations

谢谢

汤姆

I have a series of python modules written which are held in the same directory and I am having trouble with an ImportError.

The three modules I am using are draw_menu.py, errors.py and file_operations.py.

In errors.py I requires a list of error codes, I am using a custom method defined in file_operations.py to open a file containing the codes therefore I am using import file_operations just below the she-bang (above the class definition).

In file_operations.py I use a method defined in error.py to print error messages upon errors (e.g. file not found etc.). I therefore import errors in the same way here.

The above has been working fine but when I come to using draw_menu.py which uses a file to define the options in an ascii menu (therefore I am using import file_operations) an ImportError is encountered.

ImportError: cannot import name file_operations

I understand that this is because the 'import tree' if you like flows as follows:

draw_menu <- file_operations <- errors <- file_operations

It is important that each module can be used individually, why is this an issue and how can I overcome this without removing import file_operations from errors.py?

Thankyou

Tom

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦途 2024-09-16 09:18:48

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

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

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

Circular imports can cause issues in Python (as you might expect). It's probably worth checking if:

A) errors.py and file_operation.py should be single module (if they both rely so heavily on each other, do they need to be separate?)

B) you can delay the import in one or the other module. An import statement in a function will not run until the function is called, and while it's normally good practice to import at the beginning of a module there is no requirement to in Python. In situations like this it can avoid the circular reference during import.

百变从容 2024-09-16 09:18:48

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

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

The problem is not the imports themselves, but the dependencies. file_operations cannot be processed until it has imported errors, but errors cannot be processed until it has imported file_operations. Python recognises this as an impossible situation, and raises an error.

The best solution to this is to refactor your files so that you don't have this circular dependency any more. If this really isn't possible, the alternative solution is to change one of the modules so that the offending import happens inside the function that needs it, rather than at the top level. This means the initial processing of the module isn't dependent on the import, so it will succeed.

他夏了夏天 2024-09-16 09:18:48

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

问题在于 import (作为副作用)实际上会运行正在导入的模块(第一次调用 import 时)。因此,如果您正在导入一个模块,而该模块又导入了原始模块,那么事情就会变得混乱。

您可能会发现,只需在实际需要使用的点导入错误/文件操作即可缓解问题。这可以在函数内部。因此,也许将对函数的调用包装在错误中:


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

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

Apart from breaking the circular dependency you can try moving the locations of your import calls. Don't forget that imports in Python are just regular statements, so you can import inside functions for example.

The trouble is that import (as a side-effect) will actually run the module being imported (the first time you call import). So if you are importing a module, which imports the original module things get confused.

You may find that you can ease the problem by only importing errors/file_operations at the point you actually need to use it. This could be inside a function. So maybe wrap the call to the function in errors:


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

That way you will only import errors after the regular imports have run.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文