译(四十四)-Python中assert的作用

stackoverflow热门问题目录

如有翻译问题欢迎评论指出,谢谢。

最近看到用assert的代码,恰好这页第一篇就是它,缘分。

Python的assert有什么用?

  • Hossein asked:

    • 在阅读源码时我发现有的地方使用了 assert
    • 它有什么用?怎么用?
  • Answers:

    • slezica – vote: 1481

    • 大多数语言都有 assert 语句,它起到两个作用:

      1. 帮助程序尽早检测出原因已知的问题,而不用等到某些操作报错后。例如,如果没有提前捕捉到,Python 中的类型错误可能会经过几层代码之后才会出现 Exception
      2. 它可以起到文档的作用,其他工程师看到代码中的 assert 后能够保证后面代码也能正确执行。
    • 当使用下面的语句时

    • 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?
      它有什么用?怎么用?
  • Answers:

    • slezica – vote: 1481

    • The assert statement exists in almost every programming language. It has two main uses:
      大多数语言都有 assert 语句,它起到两个作用:

      1. 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
      2. 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 后能够保证后面代码也能正确执行。
    • 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 do assert(condition, message) you\’ll be running the assert 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__ is False, 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 with print(..), one may extrapolate the same to assert(..) or raise(..) 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 to True.
      第一个语句不工作是因为 bool( (False, Houston we've got a problem) ) 值为 True

    • In the statement assert(False), these are just redundant parentheses around False, which evaluate to their contents. But with assert(False,) the parentheses are now a tuple, and a non-empty tuple evaluates to True 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 that assert 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 但又没有发现他们消失的时候。

You may also like...

发表评论

您的电子邮箱地址不会被公开。

1 + 2 =