找出引发“ImportError”时真正出了什么问题
以 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
基本上问题是您的错误消息是错误的 - 导入失败还有其他原因,而不仅仅是错误的路径。
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.处理不想让异常传播但仍提供一些失败指示的情况的最简单方法是始终在打印出的任何消息中包含原始异常的详细信息:
这样,您就可以得到在常见情况下(例如,用户将设置文件放在错误的位置,或者某处存在配置错误,因此 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:
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 thesettings
module.Even better, if using the logging module, is to log the full exception details (including the traceback) as a
debug()
orinfo()
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 usingimp.find_module()
, but simply including the original error message is enough to prevent the worst hassles.接受提示。
永远不捕获导入错误。
manage.py
示例不是最佳实践。不要那样做。
导入错误应该非常非常罕见。
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.