译(四十四)-Python中assert的作用
如有翻译问题欢迎评论指出,谢谢。
最近看到用assert的代码,恰好这页第一篇就是它,缘分。
Python的assert有什么用?
Hossein asked:
- 在阅读源码时我发现有的地方使用了
assert
。 - 它有什么用?怎么用?
- 在阅读源码时我发现有的地方使用了
Answers:
slezica - vote: 1481
大多数语言都有
assert
语句,它起到两个作用:- 帮助程序尽早检测出原因已知的问题,而不用等到某些操作报错后。例如,如果没有提前捕捉到,Python 中的类型错误可能会经过几层代码之后才会出现
Exception
。 - 它可以起到文档的作用,其他工程师看到代码中的
assert
后能够保证后面代码也能正确执行。
- 帮助程序尽早检测出原因已知的问题,而不用等到某些操作报错后。例如,如果没有提前捕捉到,Python 中的类型错误可能会经过几层代码之后才会出现
当使用下面的语句时
assert condition
这会令程序去测试这个条件,条件为假时会立即触发一个错误。
Python 中它可以视作这个:
if not condition: raise AssertionError()
在 Python 的 shell 里执行:
>>> assert True # nothing happens >>> assert False Traceback (most recent call last): File "
", line 1, in AssertionError assert
还能包括额外可选信息,它能被解释器关闭,不在程序运行时执行。出错则会输出信息:
assert False, "Oh no! This assertion failed!"
不要在调用
assert
时加括号,它是语句不是函数。如果你用assert(condition, message)
的话,assert
会认为(condition, message)
是以元组的形式作为第一个参数。至于关闭它们,则要在运行时用到 Python 的可选模式令
__debug__
为False
,这样assert
语句就会被忽略。具体为加上-O
标志:python -O script.py
相关信息见文档 。
Evgeni Sergeev - vote: 549
注意括号。正如其它回答提出的那样,在 Python 3 中,
assert
是一个语句,所以不要像用print(...)
一样写成assert(...)
或者raise(...)
。这是错的:
assert(2 + 2 == 5, "Houston we've got a problem")
这才是对的:
assert 2 + 2 == 5, "Houston we've got a problem"
第一个语句不工作是因为
bool( (False, Houston we've got a problem) )
值为True
。对于语句
assert(False)
,False
外的括号时多余的,其值为括号内的语句。但对于assert(False,)
,括号会被视为元组,而非空元组在布尔环境下值为True
。Neil Vass - vote: 167
正如其它回答强调的那样,
assert
会在条件为假时抛出异常。一个重要的区别是编译时加入标志-O
后,assert
语句会被忽略。 文档中提到assert expression
可以被等效描述为:if __debug__: if not expression: raise AssertionError
这在进行彻底的代码测试时很有效,在所有的
assert
都通过了后,只需要加上标志就能发行一个优化的版本——当标志启用时,__debug__
变量将置False
,并且取消所有assert
条件的判断。但这个功能也可能造成麻烦,如果你依赖assert
但又没有发现他们消失的时候。
What is the use of assert in Python?
Hossein asked:
- I have been reading some source code and in several places I have seen the usage of
assert
.
在阅读源码时我发现有的地方使用了assert
。 - What does it mean exactly? What is its usage?
它有什么用?怎么用?
- I have been reading some source code and in several places I have seen the usage of
Answers:
slezica - vote: 1481
The
assert
statement exists in almost every programming language. It has two main uses:
大多数语言都有assert
语句,它起到两个作用:- It helps detect problems early in your program, where the cause is clear, rather than later when some other operation fails. A type error in Python, for example, can go through several layers of code before actually raising an
Exception
if not caught early on.
帮助程序尽早检测出原因已知的问题,而不用等到某些操作报错后。例如,如果没有提前捕捉到,Python 中的类型错误可能会经过几层代码之后才会出现Exception
。 - It works as documentation for other developers reading the code, who see the
assert
and can confidently say that its condition holds from now on.
它可以起到文档的作用,其他工程师看到代码中的assert
后能够保证后面代码也能正确执行。
- It helps detect problems early in your program, where the cause is clear, rather than later when some other operation fails. A type error in Python, for example, can go through several layers of code before actually raising an
When you do...
当使用下面的语句时assert condition
... you\'re telling the program to test that condition, and immediately trigger an error if the condition is false.
这会令程序去测试这个条件,条件为假时会立即触发一个错误。In Python, it\'s roughly equivalent to this:
Python 中它可以视作这个:if not condition: raise AssertionError()
Try it in the Python shell:
在 Python 的 shell 里执行:>>> assert True # nothing happens >>> assert False Traceback (most recent call last): File "
", line 1, in AssertionError Assertions can include an optional message, and you can disable them when running the interpreter.
assert
还能包括额外可选信息,它能被解释器关闭,不在程序运行时执行。To print a message if the assertion fails:
出错则会输出信息:assert False, "Oh no! This assertion failed!"
Do not use parenthesis to call
assert
like a function. It is a statement. If you doassert(condition, message)
you\'ll be running theassert
with a(condition, message)
tuple as first parameter.
不要在调用assert
时加括号,它是语句不是函数。如果你用assert(condition, message)
的话,assert
会认为(condition, message)
是以元组的形式作为第一个参数。As for disabling them, when running
python
in optimized mode, where__debug__
isFalse
, assert statements will be ignored. Just pass the-O
flag:
至于关闭它们,则要在运行时用到 Python 的可选模式令__debug__
为False
,这样assert
语句就会被忽略。具体为加上-O
标志:python -O script.py
See here for the relevant documentation.
相关信息见文档 。
Evgeni Sergeev - vote: 549
Watch out for the parentheses. As has been pointed out in other answers, in Python 3,
assert
is still a statement, so by analogy withprint(..)
, one may extrapolate the same toassert(..)
orraise(..)
but you shouldn\'t.
注意括号。正如其它回答提出的那样,在 Python 3 中,assert
是一个语句,所以不要像用print(...)
一样写成assert(...)
或者raise(...)
。This is wrong:
这是错的:assert(2 + 2 == 5, "Houston we've got a problem")
This is correct:
这才是对的:assert 2 + 2 == 5, "Houston we've got a problem"
The reason the first one will not work is that
bool( (False, Houston we've got a problem) )
evaluates toTrue
.
第一个语句不工作是因为bool( (False, Houston we've got a problem) )
值为True
。In the statement
assert(False)
, these are just redundant parentheses aroundFalse
, which evaluate to their contents. But withassert(False,)
the parentheses are now a tuple, and a non-empty tuple evaluates toTrue
in a boolean context.
对于语句assert(False)
,False
外的括号时多余的,其值为括号内的语句。但对于assert(False,)
,括号会被视为元组,而非空元组在布尔环境下值为True
。Neil Vass - vote: 167
As other answers have noted,
assert
is similar to throwing an exception if a given condition isn\'t true. An important difference is that assert statements get ignored if you compile your code with the optimization option-O
. The documentation says thatassert expression
can better be described as being equivalent to
正如其它回答强调的那样,assert
会在条件为假时抛出异常。一个重要的区别是编译时加入标志-O
后,assert
语句会被忽略。 文档中提到assert expression
可以被等效描述为:if __debug__: if not expression: raise AssertionError
This can be useful if you want to thoroughly test your code, then release an optimized version when you\'re happy that none of your assertion cases fail - when optimization is on, the
__debug__
variable becomes False and the conditions will stop getting evaluated. This feature can also catch you out if you\'re relying on the asserts and don\'t realize they\'ve disappeared.
这个在进行彻底的代码测试时很有效,在所有的assert
都通过了后,只需要加上标志就能发行一个优化的版本——当标志启用时,__debug__
变量将置False
,并且取消所有assert
条件的判断。但这个功能也可能造成麻烦,如果你依赖assert
但又没有发现他们消失的时候。
共有 0 条评论