如何在Python中禁用断言?
也就是说,如果断言失败,我不希望它抛出AssertionError
,而是继续前进。
我怎么做?
Answers:
如何在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
在正常情况下,False
当优化要求(命令行选项-O
)。
并进一步
转让给
__debug__
是非法的。内置变量的值在解释器启动时确定。
从用法文档中:
打开基本优化。这会将已编译(字节码)文件的文件扩展名从.pyc更改为.pyo。另请参阅PYTHONOPTIMIZE。
和
如果将其设置为非空字符串,则等效于指定
-O
选项。如果设置为整数,则等效于-O
多次指定。
if False: assert False
),也可以捕获断言错误。这些是您的选择。更新了答案以解决您的问题。
foo()
并关闭断言:with skip_assertion(): foo()
。这样做的好处是我不必在函数上添加其他标志
Assert
对象替换Pass
对象)。上下文管理器不会直接为此工作,但是您可以拥有某种以这种方式使用修饰功能的机制。无论如何,我不建议这样做。我怀疑您想要这样做的原因是您正在调用不受控制的代码并获得AssertionErrors。如果是这样,您可能需要找到其他修复程序。
使用-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
你应该不禁止(大多数)的断言。当注意力转移到其他地方时,它们会捕获意外错误。请参阅“十的力量”中的规则5 。
相反,可以通过以下方式保护一些昂贵的断言检查:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
保留重要断言并允许assert
优化语句的一种方法是在选择语句中引发它们:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
为False,但这是不允许的。