Python: assert and raise

The assert statement

assert_stmt ::= “assert” expression [“,” expression]
  • The simple form, assert expression, is equivalent to
if __debug__:
    if not expression: raise AssertionError
  • The extended form, assert expression1, expression2, is equivalent to
if __debug__:
    if not expression1: raise AssertionError(expression2)
  • __debug__

The built-in variable debug is True under normal circumstances, False when optimization is requested (command line option -O: Turn on basic optimizations. ). It cannot be reassigned.

  • exception AssertionError

Raised when an assert statement fails.

  • examples
>>> assert True
>>> assert False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

>>> assert 1+1 == 2
>>> assert 1 == 0, '1 is not equal to 0'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: 1 is not equal to 0
  • read more
    The assert statement

the raise statement

raise_stmt ::= “raise” [expression [“from” expression]]
  • If no expressions are present, raise re-raises the last exception that was active in the current scope. If no exception is active in the current scope, a RuntimeError exception is raised indicating that this is an error.
  • exception RuntimeError
    Raised when an error is detected that doesn’t fall in any of the other categories. The associated value is a string indicating what precisely went wrong.
  • Otherwise, raise evaluates the first expression as the exception object. It must be either a subclass or an instance of BaseException. If it is a class, the exception instance will be obtained when needed by instantiating the class with no arguments.
  • The type of the exception is the exception instance’s class, the value is the instance itself.
  • The from clause is used for exception chaining: if given, the second expression must be another exception class or instance, which will then be attached to the raised exception as the __cause__ attribute (which is writable). If the raised exception is not handled, both exceptions will be printed.
  • 1
>>> try:
...     raise IndexError('11')
... except IndexError as e:
...     print(type(e), str(e))
...
<class 'IndexError'> 11
  • 2
    當你在raise後接上例外類別時,實際上會以該類別建立實例再丟出,也就是下面兩行程式碼的作用是相同的:
raise EOFError
raise EOFError()

If it is a class, the exception instance will be obtained when needed by instantiating the class with no arguments.

  • 3

If no expressions are present, raise re-raises the last exception that was active in the current scope. If no exception is active in the current scope, a RuntimeError exception is raised indicating that this is an error.

>>> try:
...     raise EOFError
... except EOFError:
...     print('got it')
...     raise
...
got it
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
EOFError

>>> raise
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: No active exception to reraise
  • 4

The from clause is used for exception chaining: if given, the second expression must be another exception class or instance, which will then be attached to the raised exception as the __cause__ attribute (which is writable).

>>> try:
...     try:
...         raise EOFError('XD')
...     except EOFError as e:
...         print(e.args)
...         raise IndexError('Orz') from e
... except IndexError as e:
...     print(e.args)
...     print(e.__cause__.args)
...
('XD',)
('Orz',)
('XD',)
  • 5
    實際上,如果你在except中raise某個例外,則原except所比對到的例外,無論有無使用raise from,都會自動設定給 __context__
>>> try:
...     try:
...         raise EOFError('XD')
...     except EOFError as e:
...         print(e.args)
...         raise IndexError('Orz') from e
... except IndexError as e:
...     print(e.args)
...     print(e.__cause__.args)
...     print(e.__context__.args)
...
('XD',)
('Orz',)
('XD',)
('XD',)
  • 6

The type of the exception is the exception instance’s class, the value is the instance itself.

>>> try:
...   1/0
... except:
...   import sys
...   et, ei, tb = sys.exc_info()
... 
>>> et
<class 'ZeroDivisionError'>
>>> ei
ZeroDivisionError('division by zero',)
>>> tb
<traceback object at 0x7f17e68e9248>
  • 7 __traceback__

A traceback object is normally created automatically when an exception is raised and attached to it as the __traceback__ attribute, which is writable. You can create an exception and set your own traceback in one step using the with_traceback() exception method (which returns the same exception instance, with its traceback set to its argument), like so:

raise Exception("foo occurred").with_traceback(tracebackobj)
except Exception as e:
    et, ei, tb = sys.exc_info()
    ei.__traceback__ = tb
    raise ei

is the same as:

except Exception as e:
    et, ei, tb = sys.exc_info()
    raise ei.with_traceback(tb)
    原文作者:庞贝船长
    原文地址: https://www.jianshu.com/p/6d845e9e4e0e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞