Disable assertions in Python

核能气质少年 提交于 2019-12-17 04:21:28

问题


How do I disable assertions in Python?

That is, if an assertion fails, I don't want it to throw an AssertionError, but to keep going.

How do I do that?


回答1:


How do I disable assertions in Python?

There are multiple approaches that affect a single process, the environment, or a single line of code.

I demonstrate each.

For the whole process

Using the -O flag (capital O) disables all assert statements in a process.

For example:

$ python -Oc "assert False"

$ python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

Note that by disable I mean it also does not execute the expression that follows it:

$ python -Oc "assert 1/0"

$ python -c "assert 1/0"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

For the environment

You can use an environment variable to set this flag as well.

This will affect every process that uses or inherits the environment.

E.g., in Windows, setting and then clearing the environment variable:

C:\>python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError
C:\>SET PYTHONOPTIMIZE=TRUE

C:\>python -c "assert False"

C:\>SET PYTHONOPTIMIZE=

C:\>python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

Same in Unix (using set and unset for respective functionality)

Single point in code

You continue your question:

if an assertion fails, I don't want it to throw an AssertionError, but to keep going.

If you want the code that fails to be exercised, you can catch either ensure control flow does not reach the assertion, for example:

if False:
    assert False, "we know this fails, but we don't get here"

or you can catch the assertion error:

try:
    assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
    print(repr(e))

which prints:

AssertionError('this code runs, fails, and the exception is caught')

and you'll keep going from the point you handled the AssertionError.

References

From the assert documentation:

An assert statement like this:

assert expression #, optional_message

Is equivalent to

if __debug__:
    if not expression: raise AssertionError #(optional_message)

And,

the built-in variable __debug__ is True under normal circumstances, False when optimization is requested (command line option -O).

and further

Assignments to __debug__ are illegal. The value for the built-in variable is determined when the interpreter starts.

From the usage docs:

-O

Turn on basic optimizations. This changes the filename extension for compiled (bytecode) files from .pyc to .pyo. See also PYTHONOPTIMIZE.

and

PYTHONOPTIMIZE

If this is set to a non-empty string it is equivalent to specifying the -O option. If set to an integer, it is equivalent to specifying -O multiple times.




回答2:


Call Python with the -O flag:

test.py:

assert(False)
print 'Done'

Output:

C:\temp\py>C:\Python26\python.exe test.py
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    assert(False)
AssertionError

C:\temp\py>C:\Python26\python.exe -O test.py
Done



回答3:


Both of the two answers already given are valid (call Python with either -O or -OO on the command line).

Here is the difference between them:

  • -O Turn on basic optimizations. This changes the filename extension for compiled (bytecode) files from .pyc to .pyo.

  • -OO Discard docstrings in addition to the -O optimizations.

(From the Python documentation)




回答4:


Use python -O:

$ python -O
>>> assert False
>>> 



回答5:


You should NOT disable (most) assertions. They catch unanticipated errors when attention is elsewhere. See Rule 5 in "The power of ten".

Instead, guard some expensive assertion checks by something like:

import logging
logger = logging.getLogger(__name__)

if logger.getEffectiveLevel() < logging.DEBUG:
    ok = check_expensive_property()
    assert ok, 'Run !'

One way to keep important assertions, and allow assert statements to be optimized away is by raising them within a selection statement:

if foo_is_broken():
    raise AssertionError('Foo is broken!')



回答6:


Running in optimized mode should do it:

python -OO module.py


来源:https://stackoverflow.com/questions/1273211/disable-assertions-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!