为什么在第一个元素是异常的情况下提升元组呢? [英] Why raising a tuple works if first element is an Exception?

查看:153
本文介绍了为什么在第一个元素是异常的情况下提升元组呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难想出这一个,这是关于在Python 2.7中引发异常时可能会犯的错误:

  try:
raise [1,2,3,4]
除了例外例外:
print ex

这里的消息是异常必须是旧式类或派生自BaseException,而不是列表 - 这部分是可以的,但是当我将其更改为元组时,我变得困惑:

  try:
raise(1,2,3,4)
除了Exception as ex:
print ex

这里的消息是异常必须是旧式类或派生自BaseException,不是int - 为什么它被解释为提升一个int而不是一个元组?



另外:

  try:
raise(异常,'a message')
除了例外例外:
print ex

这里我们实际上上升了一个例外(与以前的e相比一致的行为例如,我们提出一个int) - 我简单地认为这只是一个替代方法:

  try:
raise异常,'一个消息'
除了例外例外:
print ex

但是在这种情况下,一条消息被传递给Exceptions ctor(如docs.python.org中所述)



有人可以解释第二和第三种情况,可能指出我在解释器中负责这个代码?

解决方案

As 记录在python参考中, raise 语句最多可以创建3个表达式来创建异常:


raise_stmt :: =raise[expression [,expression [,expression]]]


在python 2中,如果第一个表达式是元组,python将展开'元组递归地,取第一个元素,直到找到一个元组以外的东西。此行为已从Python 3中删除(请参阅 PEP 3109 。以下是合法的:

 >>> raise((异常,忽略)),'ignored' ,$ something $,$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 

该文档更详细地说明了其余内容,但是raise语句希望第一个值为Exception类,第二个值被视为异常的值(消息),第三个值是追溯。如果缺少,后面两个值将填充 None



如果第一个值是实例,则第二个值必须为无:

 >>> raise异常('something'),'something',无
追溯(最近的呼叫最后):
文件< stdin>,第1行,< module>
TypeError:实例异常可能没有单独的值

如果您使用更多的元组超过3个项目,会引发语法错误:

 >>>提升异常,某事,无,无
文件< stdin>,第1行
raise异常,'something',无,无
^
SyntaxError:invalid语法

然而,在你的情况下,你既没有提出一个类也没有提供一个实例,所以这就是Python发现的不正确如果我使用一个字符串,它也会抱怨:

 >>>提升'不是例外','something',无
追溯(最近的最后一次调用):
文件< stdin>,第1行,< module>
TypeError:异常必须是旧式类或派生自BaseException,而不是str

当然,正确的语法是:

 >>>提升异常,'something',无
追溯(最近的最后一次调用):
文件< stdin>,第1行,< module>
异常:某事


I have a hard time figuring this one out, it's about mistakes that can be done when raising an exception in Python 2.7:

try:
  raise [1, 2, 3, 4]
except Exception as ex:
  print ex

the message here is "exceptions must be old-style classes or derived from BaseException, not list" - This part is ok, but when I change it to tuple, I am getting confused:

try:
  raise (1, 2, 3, 4)
except Exception as ex:
  print ex

the message here is "exceptions must be old-style classes or derived from BaseException, not int" - why is it interpreted as raising an int, not a tuple?

Futhermore:

try:
  raise (Exception, 'a message')
except Exception as ex:
  print ex

Here we are actually rising an Exception (consistent behaviour when compared with previous example, where we were raising an int) - I briefly thought that this is just an alternate way for this:

try:
  raise Exception, 'a message'
except Exception as ex:
  print ex

But in this case, 'a message' is being passed to Exceptions ctor (as documented on docs.python.org)

Can someone explain the 2nd and 3rd cases, and possible point me to code in interpreter that is responsible for this?

解决方案

As documented in the python reference, the raise statement takes up to 3 expressions to create the exception being raised:

raise_stmt ::= "raise" [expression ["," expression ["," expression]]]

In python 2, if the first expression is a tuple, python will 'unwrap' the tuple recursively, taking the first element until it finds something other than a tuple. This behavior is being removed from Python 3 (see PEP 3109. The following is legal:

>>> raise ((Exception, 'ignored'), 'ignored'), 'something', None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: something

The documentation explains the rest in more detail, but the raise statement expects the first value to be a Exception class, the second value is seen as the value of the exception (the message) and the third value is a traceback. Python fills in None for the latter two values if missing.

If the first value is a instance instead, the second value must be None:

>>> raise Exception('something'), 'something', None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: instance exception may not have a separate value

If you use a tuple of more than 3 items, it'll raise a syntax error:

>>> raise Exception, 'something', None, None
  File "<stdin>", line 1
    raise Exception, 'something', None, None
                                      ^
SyntaxError: invalid syntax

In your case however, you raised neither a class nor an instance, so that's what Python found to be incorrect first; if I use a string it'll complain too:

>>> raise 'not an exception', 'something', None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: exceptions must be old-style classes or derived from BaseException, not str

The correct syntax is of course:

>>> raise Exception, 'something', None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: something

这篇关于为什么在第一个元素是异常的情况下提升元组呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆