找出引发“ImportError”时真正出了什么问题

发布于 2024-10-18 15:31:27 字数 507 浏览 3 评论 0原文

以 Django 为例,在 manage.py 中:

try:
    import settings
except ImportError:
    sys.stderr.write("Error: Can't find the file 'settings.py'...")

看起来合法,但是当 settings 导入 non_existant_lib_foo 时会发生什么?

好吧,你会徒劳无功地寻找你可以用 PATH 等完成的所有可能的事情。

当然,你可以使用 except ImportError as e: 并且只是打印出实际的错误消息,但是如果您只想捕获特定错误并提供非常好的建议(如上面所示),该怎么办?

您只能或多或少地使用正则表达式,或者最多猜测“正确的”模块导入失败,然后显示消息。

有更好的方法来处理这个问题吗?

Take Django for instance, in manage.py:

try:
    import settings
except ImportError:
    sys.stderr.write("Error: Can't find the file 'settings.py'...")

Seems legit, but what happens when settings imports non_existant_lib_foo?

Well, you're sent on a goose chase for all the possible things you could have done with PATH, etc.

Of course you can use except ImportError as e: and just print out the actual error message, but what if you want to catch only a specific error and give a really good bit of advice, like above?

You're left to using regexp more or less or, at best, guessing that the "right" module failed importing, and then display the message.

Is there a better way to handle this?

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

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

发布评论

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

评论(3

吻泪 2024-10-25 15:31:27

基本上问题是您的错误消息是错误的 - 导入失败还有其他原因,而不仅仅是错误的路径。 ImportError 只是意味着“您不能使用此模块,请查看回溯以找出原因”,您只是得出了结论。

如果您想显示“找不到文件”,那么您应该先查找该文件。 imp.find_module 就是这样做的。

Basically the problem is that your error message is wrong - there are other reasons why import can fail, not just wrong paths. ImportError simply means "you cannot use this module, look at the traceback to find out why", you just jumped to a conclusion.

If you want to display "Can't find the file" then you should look for the file first. imp.find_module does that.

高速公鹿 2024-10-25 15:31:27

处理不想让异常传播但仍提供一些失败指示的情况的最简单方法是始终在打印出的任何消息中包含原始异常的详细信息:

try:
    import settings
except ImportError as exc:
    sys.stderr.write("Error: failed to import settings module ({})".format(exc))

这样,您就可以得到在常见情况下(例如,用户将设置文件放在错误的位置,或者某处存在配置错误,因此 sys.path 是错误的),不会完全掩盖出现的任何其他导入错误在 settings 模块的执行中。

如果使用日志记录模块,更好的方法是将完整的异常详细信息(包括回溯)记录为 debug()info() 日志记录事件。

还有其他选项,例如执行子字符串搜索 if 'settings' not in str(exc): raise 或使用 imp.find_module() 将模块的位置与其执行分离,但简单地包含原始错误消息就足以防止最严重的麻烦。

The simplest way to handle cases where you don't want to let the exception propagate, but still provide some indication of the failure, is to always include the details from the original exception in whatever message you print out:

try:
    import settings
except ImportError as exc:
    sys.stderr.write("Error: failed to import settings module ({})".format(exc))

That way, you get the clear message in the common case (e.g. the user put their settings file in the wrong place, or there is a configuration error somewhere so sys.path is wrong), without completely obscuring any other import errors that arise in the execution of the settings module.

Even better, if using the logging module, is to log the full exception details (including the traceback) as a debug() or info() logging event.

There are other options, such as doing a substring search if 'settings' not in str(exc): raise or separating the location of the module from its execution by using imp.find_module(), but simply including the original error message is enough to prevent the worst hassles.

怼怹恏 2024-10-25 15:31:27

我发现真正令人沮丧的一件事是,当您陷入导入错误时,您真的会立即掉进一个很深的兔子洞。

接受提示。

永远捕获导入错误。 manage.py 示例不是最佳实践。

不要那样做。

导入错误应该非常非常罕见。

One thing I've found really frustrating is that when you trap an import error you're really going down a deep rabbit hole right away.

Take the hint.

Do not trap import errors ever. The manage.py example is not a best practice.

Do not do that.

import errors should be very, very rare.

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