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

后端 未结 3 1388
一生所求
一生所求 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:27

    Apparently Python accepts also a non-empty tuple for the first expression in a raise statement despite the documentation (but as stated in this PEP), and if it's a tuple, it uses recursively its first element for the class of the exception. Let me show you some code:

    >>> raise ValueError, 'sdf', None
    Traceback (most recent call last):
      File "", line 1, in 
    ValueError: sdf
    
    >>> raise (ValueError, 5), 'sdf', None
    Traceback (most recent call last):
      File "", line 1, in 
    ValueError: sdf
    

    Despite what I've said in my previous comment, there is no auto-unpacking, because the string is not passed to the exception class in my next example:

    >>> raise (ValueError, 'sdf', None)
    Traceback (most recent call last):
      File "", line 1, in 
    ValueError
    

    Also using the python ast module, we can see that in a raise expression there is no tuple by default:

    >>> ast.dump(ast.parse('raise ValueError, "asd"'))
    "Module(body=[Raise(type=Name(id='ValueError', ctx=Load()), inst=Str(s='asd'), tback=None)])"
    

    And if we use a tuple, that's passed as the type argument:

    >>> ast.dump(ast.parse('raise (ValueError, "asd")'))
    "Module(body=[Raise(type=Tuple(elts=[Name(id='ValueError', ctx=Load()), Str(s='asd')], ctx=Load()), inst=None, tback=None)])"
    

提交回复
热议问题