在Python中禁用断言

119 投票
6 回答
52139 浏览
提问于 2025-04-15 13:35

我该怎么在Python中关闭断言功能呢?

也就是说,如果一个断言失败了,我不想让它抛出一个AssertionError错误,而是希望程序继续运行。

我该怎么做呢?

6 个回答

18

之前给出的两个答案都是正确的(在命令行中用 -O-OO 来调用 Python)。

根据Python 的官方文档,这两者的区别如下:

  • -O 开启基本的优化。这会把编译后的文件(字节码文件)的扩展名从 .pyc 改为 .pyo。

  • -OO 除了进行 -O 的优化外,还会丢弃文档字符串。

要检查断言是否启用,可以查看 __debug__ 的值。

63

用-O标志来调用Python:

test.py:

assert False
print('Done')

输出:

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
122

#如何在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 expression #, optional_message

相当于

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

而且,

内置变量__debug__在正常情况下是True,当请求优化时(命令行选项-O)则为False

进一步说

__debug__的赋值是非法的。这个内置变量的值是在解释器启动时确定的。

来自使用文档:

-O

开启基本优化。这会将编译(字节码)文件的文件扩展名从.pyc改为.pyo。另见PYTHONOPTIMIZE。

还有

PYTHONOPTIMIZE

如果这个变量设置为非空字符串,相当于指定-O选项。如果设置为整数,相当于多次指定-O

撰写回答