Why raising a tuple works if first element is an Exception?

后端 未结 3 1350
一生所求
一生所求 2021-02-02 10:46

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 Excepti         


        
3条回答
  •  独厮守ぢ
    2021-02-02 11:29

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

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

    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 "", line 1, in 
    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 "", line 1, in 
    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 "", 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 "", line 1, in 
    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 "", line 1, in 
    Exception: something
    

提交回复
热议问题