断言是什么意思?它是如何使用的?


当前回答

assert语句几乎存在于每一种编程语言中。它有助于在程序的早期(原因很清楚的时候)检测问题,而不是在稍后作为其他操作的副作用检测问题。他们总是期待一个真实的条件。

当你这样做的时候:

assert condition

您告诉程序测试该条件,如果为假,则立即触发错误。

在Python中,assert表达式等价于:

if __debug__:
    if not <expression>: raise AssertionError

你可以使用扩展表达式来传递一个可选的消息:

if __debug__:
    if not (expression_1): raise AssertionError(expression_2)

在Python解释器中试试:

>>> assert True # Nothing happens because the condition returns a True value.
>>> assert False # A traceback is triggered because this evaluation did not yield an expected value.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

在使用它们之前有一些注意事项,主要是针对那些认为在assert和if语句之间切换的人。使用assert的目的是在某些情况下,当程序验证一个条件并返回一个值时,应该立即停止程序,而不是采取其他方法来绕过错误:

1. 括号

您可能已经注意到,assert语句使用了两个条件。因此,不要用圆括号把它们括起来作为一个明显的建议。如果你这样做:

assert (condition, message)

例子:

>>> assert (1==2, 1==1)
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?

你将使用(condition, message)运行断言,它表示一个元组作为第一个参数,这是因为Python中的非空元组总是True。但是,你可以单独做,没有问题:

assert (condition), "message"

例子:

>>> assert (1==2), ("This condition returns a %s value.") % "False"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: This condition returns a False value.

2. 调试的目的

如果你想知道什么时候使用assert语句。举一个现实生活中的例子:

*当你的程序倾向于控制用户输入的每个参数时:

def loremipsum(**kwargs):
    kwargs.pop('bar') # return 0 if "bar" isn't in parameter
    kwargs.setdefault('foo', type(self)) # returns `type(self)` value by default
    assert (len(kwargs) == 0), "unrecognized parameter passed in %s" % ', '.join(kwargs.keys())

*另一种情况是在数学中,0或非正作为某个方程的系数或常数:

def discount(item, percent):
    price = int(item['price'] * (1.0 - percent))
    print(price)
    assert (0 <= price <= item['price']),\
            "Discounted prices cannot be lower than 0 "\
            "and they cannot be higher than the original price."

    return price

*甚至是一个简单的布尔实现的例子:

def true(a, b):
    assert (a == b), "False"
    return 1

def false(a, b):
    assert (a != b), "True"
    return 0

3.数据处理或数据验证

最重要的是不要依赖assert语句来执行数据处理或数据验证,因为该语句可以在Python初始化时使用- o或- oo标记(分别表示值1、2和0(默认值))或PYTHONOPTIMIZE环境变量关闭。

价值1:

* assert被禁用;

*字节码文件使用.pyo而不是.pyc扩展名生成;

* sys.flags.optimize设置为1 (True);

*和,__debug__被设置为False;

值2:禁用一个东西

*文档字符串被禁用;

因此,使用assert语句来验证一种预期的数据是极其危险的,甚至意味着存在一些安全问题。然后,如果你需要验证一些权限,我建议你提出AuthError代替。作为有效的前置条件,assert通常由程序员在不与用户直接交互的库或模块上使用。

其他回答

在Python中,断言的目标是通知开发人员程序中不可恢复的错误。

断言并不是为了表明预期的错误条件,比如“文件未找到”,用户可以采取纠正措施(或者只是重试)。

另一种看待它的方法是,断言是代码中的内部自检。它们通过在代码中声明一些不可能的条件来工作。如果这些条件不成立,则意味着程序中存在错误。

如果您的程序没有错误,这些情况将永远不会发生。但如果其中一个确实发生了,程序将崩溃,并提示一个断言错误,告诉您究竟触发了哪个“不可能”条件。这使得跟踪和修复程序中的错误变得更加容易。

以下是我写的Python断言教程的摘要:

Python的assert语句是一种调试辅助,而不是处理运行时错误的机制。使用断言的目标是让开发人员更快地找到错误的可能根源。除非程序中存在错误,否则绝不应引发断言错误。

断言是在我们的程序中自信地陈述事实的语句。

语法:assert <条件>或assert <条件>,<错误消息>

它有一个条件/表达式,它应该总是为真。如果条件为false, assert语句将停止程序并抛出AssertionError错误消息。你的断言表达式将是你不希望在程序中出现的东西。

e.g.

Assert <条件>——使用Assert而没有<错误消息> var = int(输入("输入值1-9包含:")) 断言var != 0 打印(var) 输出: 如果输入为0: AssertionError 如果输入为1: 1 断言<条件>,<错误消息>——使用带有<错误消息>的断言 var = int(输入("输入值1-9包含:")) 断言var !=0,"输入不能为零" 打印(var) 输出: 如果输入为0: AssertionError:输入不能为零 如果输入为1: 1

重点:

它被用作调试工具。 它接受一个表达式和一个可选消息。 它几乎存在于每一种编程语言中

assert语句有两种形式。

简单形式assert <expression>相当于

if __​debug__:
    if not <expression>: raise AssertionError

扩展形式assert <expression1>, <expression2>等价于

if __​debug__:
    if not <expression1>: raise AssertionError(<expression2>)

其他人已经为您提供了文档链接。

您可以在交互式shell中尝试以下操作:

>>> assert 5 > 2
>>> assert 2 > 5
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
builtins.AssertionError:

第一个语句什么都不做,而第二个语句引发异常。这是第一个提示:断言用于检查在代码的给定位置(通常是函数的开始(前置条件)和结束(后置条件)中应该为真条件。

断言实际上与契约编程高度相关,这是一种非常有用的工程实践:

http://en.wikipedia.org/wiki/Design_by_contract。

格式: 断言表达式(参数) 当assert遇到语句时,Python对表达式求值。如果语句不为真,则引发异常(assertionError)。 如果断言失败,Python使用ArgumentExpression作为AssertionError的参数。可以像使用try-except语句一样捕获和处理AssertionError异常,但如果没有处理,它们将终止程序并产生跟踪。 例子:

def KelvinToFahrenheit(Temperature):    
    assert (Temperature >= 0),"Colder than absolute zero!"    
    return ((Temperature-273)*1.8)+32    
print KelvinToFahrenheit(273)    
print int(KelvinToFahrenheit(505.78))    
print KelvinToFahrenheit(-5)    

当执行上面的代码时,它会产生以下结果:

32.0
451
Traceback (most recent call last):    
  File "test.py", line 9, in <module>    
    print KelvinToFahrenheit(-5)    
  File "test.py", line 4, in KelvinToFahrenheit    
    assert (Temperature >= 0),"Colder than absolute zero!"    
AssertionError: Colder than absolute zero!