在 Python 中禁用断言
- 2025-03-11 08:54:00
- admin 原创
- 72
问题描述:
如何在 Python 中禁用断言?
也就是说,如果断言失败,我不希望它抛出AssertionError
,而是继续前进。
我该如何做?
解决方案 1:
如何在 Python 中禁用断言?
有多种方法可以影响单个进程、环境或单行代码。
我会逐一进行演示。
整个过程
使用-O
标志(大写 O)可禁用进程中的所有断言语句。
例如:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
请注意,我所说的禁用是指它也不会执行其后面的表达式:
$ 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
对于环境
您也可以使用环境变量来设置此标志。
这将影响使用或继承该环境的每个进程。
例如,在 Windows 中,设置然后清除环境变量:
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
与 Unix 相同(使用 set 和unset实现相应的功能)
代码中的单点
你继续你的问题:
如果断言失败,我不希望它抛出 AssertionError,而是继续运行。
您可以确保控制流不会到达断言,例如:
if False:
assert False, "we know this fails, but we don't get here"
或者如果您希望断言表达式被执行,那么您可以捕获断言错误:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
打印结果为:
AssertionError('this code runs, fails, and the exception is caught')
你 会 从 你 处理 的 那个 点 继续 前进AssertionError
.
参考
来自文档assert
:
像这样的断言语句:
assert expression #, optional_message
相当于
if __debug__: if not expression: raise AssertionError #(optional_message)
和,
内置变量
__debug__
在True
正常情况下,False
当请求优化时(命令行选项-O
)。
以及进一步
赋值
__debug__
是非法的。内置变量的值是在解释器启动时确定的。
来自使用文档:
-O
启用基本优化。这会将已编译(字节码)文件的文件扩展名从 .pyc 更改为 .pyo。另请参阅 PYTHONOPTIMIZE。
和
优化
如果设置为非空字符串,则相当于指定选项
-O
。如果设置为整数,则相当于指定-O
多次。
解决方案 2:
使用 -O 标志调用 Python:
测试.py:
assert False
print('Done')
输出:
C: emppy>C:Python26python.exe test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
assert(False)
AssertionError
C: emppy>C:Python26python.exe -O test.py
Done
解决方案 3:
已经给出的两个答案都是有效的(在命令行上使用-O
或调用 Python)。-OO
根据Python 文档,它们之间的区别如下:
-O
启用基本优化。这会将已编译(字节码)文件的文件扩展名从 .pyc 更改为 .pyo。-OO
除了优化之外,还丢弃文档字符串-O
。
要检查断言是否启用或禁用,请查看的值__debug__
。
解决方案 4:
使用python -O
:
$ python -O
>>> assert False
>>>
解决方案 5:
您不应该禁用断言。当注意力在其他地方时,它们会捕获意外错误。请参阅“十的力量”中的规则 5 (DOI,维基百科)。
写raise
语句,而不是assert
语句:
if x_is_broken():
raise RuntimeError('`x` is broken.')
raise
无论使用哪种优化选项运行 Python,语句始终存在。此外,使用语句raise
可以指定不同于的异常类型AssertionError
。这对用户非常有用。此外,只需编写一个raise
语句,就会促使人们问自己AssertionError
这是否是正确的选择。
此外,在编写raise
语句时,我们通常会写一条信息性消息,例如raise AssertionError('An error occurred with
x.')
。在语句中可以写assert
一条错误消息(例如,assert x, 'An error occurred with
x.'
和 括号可用于表示多行消息),但是,可能会忘记。相反,raise AssertionError(....)
要求....
填写 (并且这种形式raise AssertionError
不常见,不推荐)。
当编写错误消息时,会发现有多少进一步的编码错误会引人注目。
旁注:计算量大的断言检查只能在需要时运行。一种方法是:
import logging
log = logging.getLogger(__name__)
if log.getEffectiveLevel() < logging.DEBUG:
if not check_expensive_property(x):
raise RuntimeError('`x` is broken.')
解决方案 6:
在优化模式下运行应该可以做到:
python -OO module.py
扫码咨询,免费领取项目管理大礼包!