为什么我在 Python 上遇到不一致的异常?

发布于 2024-09-17 23:38:29 字数 842 浏览 1 评论 0原文

我在Python中遇到了一个非常奇怪的行为,一种不一致的行为。

...
except IOError as msg:
    sys.exit("###ERROR IOError: %s" % (msg))

通常这会给我一条消息,例如:

###ERROR IOError: [Errno 13] Permission denied: 'filename'

在相同的情况下,上面的代码给我一个元组而不是正确的错误消息。

###ERROR IOError: (13, 'Permission denied')

这很奇怪,因为在所有情况下,异常都来自同一个 python 方法,codecs.open(...)

让我更多地想知道的是,如果我删除处理,异常将达到上层始终具有正确的文本(完整的错误消息)!

except IOError as msg:
    print(msg)
    raise msg

上面的示例将总是打印一条完整的消息,例如IOError: [Errno 13] Permission returned: u'filename'

为什么会发生这种情况以及如何防止这种情况,我不想向用户提供不完整的错误消息。

我想在测试文件中重现此行为,但无法在项目外重现此行为。

我怀疑这与 sys.exit() 的使用有关,因为 print(msg) 会给出良好的结果,但 sys.exit > 不。

I encountered a very strange behavior in Python, a behavior that is not consistent.

...
except IOError as msg:
    sys.exit("###ERROR IOError: %s" % (msg))

Usually this would get me a message like:

###ERROR IOError: [Errno 13] Permission denied: 'filename'

In same cases the above code is giving me a tuple instead of a proper error message.

###ERROR IOError: (13, 'Permission denied')

This is very strange because in all case the exception come from the same python method, codecs.open(...)

What makes me wonder more about this is that if I remove the handling the exception will reach upper levels with the right text (full error message), always!

except IOError as msg:
    print(msg)
    raise msg

The above example will always print a complete message, like IOError: [Errno 13] Permission denied: u'filename'.

Why is this happening and how do I prevent this, I don't want to give incomplete error messages to the users.

I wanted to reproduce this behavior in a test file, but I was not able to reproduce this outside the project.

I suspect that is has something to do with the usage of sys.exit() because print(msg) will give good result but sys.exit not.

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

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

发布评论

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

评论(3

久光 2024-09-24 23:38:29

首先,当重新引发异常时,决不执行except Exc as e: raise e。它总是只是简单的raise,没有参数。这将保留回溯。

不,这与 sys.exit 无关,而与异常的实例化方式有关。你总是会遇到异常;只是有时它的字符串表示形式会类似于元组的表示形式。

>>> print IOError(13, 'Permission denied')
[Errno 13] Permission denied
>>> print IOError((13, 'Permission denied'))
(13, 'Permission denied')

如果不显示完整的回溯,就无法以这种方式判断到底是什么引发了错误。另外,如果没有像我指出的那样正确重新提高,您将无法获得完整的回溯。

First, when reraising an exception, never do except Exc as e: raise e. It is always just plain raise with no arguments. This will preserve the traceback.

No, this has nothing to do with sys.exit and everything to do with how the exception was instantiated. You are always getting an exception; just sometimes its string representation will resemble that of a tuple.

>>> print IOError(13, 'Permission denied')
[Errno 13] Permission denied
>>> print IOError((13, 'Permission denied'))
(13, 'Permission denied')

Without showing the full traceback, there's no way to tell what exactly is raising the error in this way. Also, without properly reraising like I pointed out, you won't be getting the full traceback.

压抑⊿情绪 2024-09-24 23:38:29

在 Python 1.5 之前,异常是字符串。之后他们将其更改为类以保持向后兼容性。现在你只能引发异常实例或类。

我想有这样的代码:

error = (13, 'Permision denied')

#more code

raise error

在他们将其更改为异常之后,有人做了:

raise IOError(error)

Before Python 1.5 exceptions were strings. After that they changed it to classes to maintain backwards compatibility. Nowadays you can only raise exception instances or classes.

I imagine there was a code like this:

error = (13, 'Permision denied')

#more code

raise error

After they changed it to exception somebody just did:

raise IOError(error)
拍不死你 2024-09-24 23:38:29

我建议您不要依赖异常的字符串表示形式;您可以将其命名为 msg,但它既不是字符串也不是消息;这是一个异常实例。

因此,您可能希望从 msg.args 元组构造自己的字符串,并将其用作要显示的“消息”。

I would suggest that you don't depend on the string representation of the exception; you might name it msg, but it's neither a string nor a message; it's an exception instance.

So you might want to construct your own string from the msg.args tuple, and use that as the “message” you want to display.

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