Answers:
该assert
语句几乎存在于每种编程语言中。它有助于在程序中尽早发现问题,找出原因,而不是在其他操作后再发现问题。
当你做...
assert condition
...您要告诉程序测试该条件,如果条件为假,则立即触发错误。
在Python中,它大致等于:
if not condition:
raise AssertionError()
在Python Shell中尝试:
>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
断言可以包括可选消息,您可以在运行解释器时将其禁用。
要在断言失败时打印消息:
assert False, "Oh no! This assertion failed!"
千万不能使用括号调用assert
的功能等。这是一个声明。如果你这样做assert(condition, message)
你会运行assert
一个(condition, message)
元组的第一个参数。
至于禁用它们,运行时,python
在优化模式,其中__debug__
是False
,断言语句将被忽略。只要通过-O
标志:
python -O script.py
有关相关文档,请参见此处。
if not condition: raise AssertError()
,为什么要使用assert?除了仅是简短的if not condition
陈述形式之外,是否有其他条件可以使assert更好?
if
)。阅读文档以获取更多信息:)
assert
,但是在阅读所有答案之后,我什么都没得到!
注意括号。正如上面指出的那样,在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
布尔值。
assert (2 + 2 = 5), "Houston we've got a problem"
应该可以,是吗?
assert (2 + 2 = 5), "Houston we've got a problem"
不会起作用...但是与assert语句无关,这很好。您的状况不起作用,因为它不是状况。错过了一秒钟=
。
正如其他答案所指出的,assert
类似于在给定条件不成立时引发异常。一个重要的区别是,如果使用优化选项编译代码,则assert语句将被忽略-O
。该文档说,assert expression
可以更好地描述为等同于
if __debug__:
if not expression: raise AssertionError
如果您要彻底测试代码,然后在满意所有断言都不失败的情况下发布优化版本,这将非常有用-当优化打开时,__debug__
变量变为False且条件将不再被求值。如果您依靠断言并且没有意识到它们已经消失,那么此功能还可以吸引您。
if Not Error: raise Exception(“ this is a error”)
?这样,当用户运行该程序时,该程序仍将显示错误的来源
assert
语句吗?这里的假设是,当程序发布给最终用户时,您正在使用-O标志,因此假定所有错误均已删除。因此,任何错误或程序崩溃都是由于根据合同有效地输入了程序而无法由程序处理的。因此,它应该这样警告用户。
Python中断言的目的是通知开发人员程序中不可恢复的错误。
断言并不旨在表示预期的错误情况,例如“找不到文件”,用户可以在其中采取纠正措施(或只是再试一次)。
另一种看待它的方式是说断言是代码中的内部自检。它们通过在代码中声明某些条件是不可能的来工作的。如果不满足这些条件,则意味着程序中存在错误。
如果您的程序没有错误,则这些情况将永远不会发生。但是,如果确实发生了其中一种情况,则程序将因声明错误而崩溃,并确切地告诉您触发了哪个“不可能”条件。这使查找和修复程序中的错误变得更加容易。
这是我写的有关Python断言的教程的摘要:
Python的assert语句是一种调试辅助工具,而不是用于处理运行时错误的机制。使用断言的目的是让开发人员更快地找到错误的可能根本原因。除非程序中存在错误,否则永远不会引发断言错误。
assert
陈述以及何时使用它。我试图理解您在本文中介绍的许多术语。
assert store.product_exists(product_id), 'Unknown product id'
不是一个很好的做法,因为如果调试被关闭,则user
即使不是admin
就能删除产品。您认为assert user.is_admin()
是unrecoverable
错误吗?为什么不是这样self-check
?
assert statement
,price
也不能将其视为用户输入吗?为什么将您视为assert user.is_admin()
数据验证而不是assert price
?
其他人已经为您提供了指向文档的链接。
您可以在交互式外壳中尝试以下操作:
>>> assert 5 > 2
>>> assert 2 > 5
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
builtins.AssertionError:
第一条语句什么也不做,而第二条语句引发异常。这是第一个提示:断言对于检查在代码的给定位置应为真的条件(通常是函数的开始(前提)和结束(条件))很有用。
断言实际上与合同编程高度相关,这是非常有用的工程实践:
从文档:
Assert statements are a convenient way to insert debugging assertions into a program
在这里您可以阅读更多信息:http : //docs.python.org/release/2.5.2/ref/assert.html
断言是检查程序内部状态是否符合程序员预期的一种系统方法,目的是捕获错误。请参见下面的示例。
>>> number = input('Enter a positive number:')
Enter a positive number:-1
>>> assert (number > 0), 'Only positive numbers are allowed!'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Only positive numbers are allowed!
>>>
该assert
语句几乎存在于每种编程语言中。它有助于在程序中尽早发现问题,找出原因,而不是在其他操作后再发现问题。他们总是期待一个True
条件。
当您执行以下操作时:
assert condition
您要告诉程序测试该条件并在错误的情况下立即触发错误。
在Python中,assert
expression等效于:
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
是在程序验证条件并返回应立即停止程序的值的情况下,而不是采取某些替代方法来绕过错误:
您可能已经注意到,该assert
语句使用两个条件。因此,千万不能使用括号englobe他们作为一个显而易见的建议。如果您这样做:
assert (condition, message)
例:
>>> assert (1==2, 1==1)
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?
您将以代表元组的第一个参数运行assert
带有的a (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.
如果您想知道何时使用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
最重要的是不要依赖该assert
语句执行数据处理或数据验证,因为可以在Python初始化时使用-O
或-OO
标志(分别表示值1、2和0(默认值)或PYTHONOPTIMIZE
环境变量)关闭此语句。。
值1:
*断言被禁用;
*使用.pyo
扩展名而不是.pyc
; 生成字节码文件;
* sys.flags.optimize
设置为1(True
);
*和,__debug__
设置为False
;
值2:再禁用一件事
*文档字符串被禁用;
因此,使用该assert
语句来验证某种预期数据非常危险,这甚至暗示了某些安全问题。然后,如果您需要验证某些权限,我建议您raise AuthError
代替。作为先决条件,assert
程序员通常在没有用户直接交互的库或模块上使用an 。
正如在C2 Wiki上简要概述的那样:
断言是程序中特定点的布尔表达式,除非程序中存在错误,否则该表达式为真。
您可以使用一条assert
语句来记录您在特定程序点上对代码的理解。例如,您可以记录关于输入(前提条件),程序状态(不变式)或输出(后置条件)的假设或保证。
如果您的断言失败了,这将向您(或您的后继者)发出警报,提醒您在编写程序时对程序的理解是错误的,并且可能包含错误。
有关更多信息,John Regehr在“ Assertions”中有一篇精彩的博客文章,该文章也适用于Python assert
语句。
Python 断言基本上是一种调试辅助工具,用于测试代码内部自检的条件。当代码陷入不可能的情况时,Assert使调试变得非常容易。断言检查那些不可能的情况。
假设有一个函数可以计算折扣后的商品价格:
def calculate_discount(price, discount):
discounted_price = price - [discount*price]
assert 0 <= discounted_price <= price
return discounted_price
在这里,Discounted_price永远不能小于0且大于实际价格。因此,如果违反了上述条件,则assert会引发Assertion Error,这将有助于开发人员识别出某些不可能的事情发生了。
希望能帮助到你 :)
assert
在调试上下文中很有用,但不应依赖于调试上下文之外。
我的简短解释是:
assert
AssertionError
如果expression为false,则引发,否则继续执行代码,如果有逗号,则为AssertionError: whatever after comma
,并且代码如下:raise AssertionError(whatever after comma)
有关此的相关教程:
https://www.tutorialspoint.com/python/assertions_in_python.htm
assert
,但没有提供何时使用(或不使用)an的信息assert
;还指出,一个assert
可以禁用如果__debug__
IS False
将是有益的。
在Pycharm中,如果assert
与一起使用isinstance
来声明对象的类型,它将使您在编码时可以访问父对象的方法和属性,它将自动自动完成。
例如,假设self.object1.object2
是一个MyClass
对象。
import MyClasss
def code_it(self):
testObject = self.object1.object2 # at this point, program doesn't know that testObject is a MyClass object yet
assert isinstance(testObject , MyClasss) # now the program knows testObject is a MyClass object
testObject.do_it() # from this point on, PyCharm will be able to auto-complete when you are working on testObject
如在其他答案中所写,assert
语句用于检查给定点的程序状态。
我不会重复有关关联消息,括号或-O
选项和__debug__
常量的内容。另请查阅文档以获取第一手信息。我将重点关注您的问题:的用途是assert
什么?更准确地说,何时(何时不该使用)assert
?
该assert
语句对于调试程序很有用,但不鼓励检查用户输入。我使用以下经验法则:保留断言以检测这种不应该发生的情况。用户输入可能不正确,例如密码太短,但这不是不应该发生的情况。如果圆的直径不是其半径的两倍,则在这种情况下不应该发生。
最有趣的,在我脑海里,使用的assert
是由灵感
合同编程为[面向对象的软件建设]由B.迈耶描述(
https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction% 2C_2nd_Edition
)并以[Eiffel编程语言](https://en.wikipedia.org/wiki/Eiffel_ (programming_language
))实施。您不能使用该assert
语句通过合同完全模拟编程,但是保持意图很有趣。
这是一个例子。想象一下,您必须编写一个head
函数(例如head
Haskell中的[ 函数](
http://www.zvon.org/other/haskell/Outputprelude/head_f.html))。给出的规范是:“如果列表不为空,则返回列表的第一项”。查看以下实现:
>>> def head1(xs): return xs[0]
和
>>> def head2(xs):
... if len(xs) > 0:
... return xs[0]
... else:
... return None
(是的,可以写成return xs[0] if xs else None
,但这不是重点)。
如果列表不为空,则两个函数的结果相同,并且此结果正确:
>>> head1([1, 2, 3]) == head2([1, 2, 3]) == 1
True
因此,这两种实现都是(我希望)正确的。当您尝试采用空列表的标题时,它们会有所不同:
>>> head1([])
Traceback (most recent call last):
...
IndexError: list index out of range
但:
>>> head2([]) is None
True
同样,这两种实现都是正确的,因为没有人应该将空列表传递给这些函数(我们超出了规范)。那是一个不正确的电话,但是如果您进行这样的电话,任何事情都会发生。一个函数引发异常,另一个函数返回一个特殊值。最重要的是:我们不能依靠这种行为。如果xs
为空,则可以使用:
print(head2(xs))
但这将使程序崩溃:
print(head1(xs))
为避免意外,我想知道何时将一些意外的参数传递给函数。换句话说:我想知道何时可观察的行为不可靠,因为它取决于实现而不是规范。当然,我可以阅读规范,但是程序员并不总是仔细阅读文档。
想象一下,如果我有一种方法可以将规范插入代码中以达到以下效果:当我违反规范时,例如,通过向传递一个空列表head
,我会得到警告。这将对编写正确的(即符合规范的)程序有很大的帮助。这就是assert
进入现场的地方:
>>> def head1(xs):
... assert len(xs) > 0, "The list must not be empty"
... return xs[0]
和
>>> def head2(xs):
... assert len(xs) > 0, "The list must not be empty"
... if len(xs) > 0:
... return xs[0]
... else:
... return None
现在,我们有:
>>> head1([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty
和:
>>> head2([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty
请注意,它head1
抛出一个AssertionError
,而不是IndexError
。这很重要,因为an AssertionError
并不是任何运行时错误:它表示违反规范。我想要警告,但出现错误。幸运的是,我可以禁用该检查(使用该-O
选项),但后果自负。我会做到的,崩溃真的很昂贵,并且希望最好。想象一下,我的程序嵌入在穿过黑洞的宇宙飞船中。我将禁用断言,并希望该程序足够健壮,以免崩溃的时间尽可能长。
此示例仅与前提条件有关,因为您可以使用它assert
来检查后置条件(返回值和/或状态)和不变式(类的状态)。请注意,检查后置条件和不变量with assert
可能很麻烦:
您不会拥有像Eiffel那样复杂的功能,但是可以提高程序的整体质量。
总而言之,该assert
语句是检测这种不应该发生的情况的便捷方法。违反规范(例如,向传递一个空列表head
)是头等舱,这种情况不应该发生。因此,尽管该assert
语句可用于检测任何意外情况,但这是确保满足规范的一种特权方式。一旦将assert
语句插入代码中以表示规范,我们就可以希望您提高了程序的质量,因为将报告错误的参数,错误的返回值,错误的类状态...。
格式:assert Expression [,arguments]当assert遇到一条语句时,Python计算该表达式。如果该语句不为true,则会引发异常(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!
def getUser(self, id, Email):
user_key = id and id or Email
assert user_key
可用于确保在函数调用中传递参数。
if not user_key: raise ValueError()
请在此处使用“ 检查最后2个段落”:wiki.python.org/moin/UsingAssertionsEffectively
assert
不应用于输入验证,因为如果__debug__
为is ,验证将被剥离False
。同样将断言用于非调试目的也会导致人们捕获结果AssertionError
s,这会使调试变得困难而不是更少。
>>>this_is_very_complex_function_result = 9
>>>c = this_is_very_complex_function_result
>>>test_us = (c < 4)
>>> #first we try without assert
>>>if test_us == True:
print("YES! I am right!")
else:
print("I am Wrong, but the program still RUNS!")
I am Wrong, but the program still RUNS!
>>> #now we try with assert
>>> assert test_us
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
assert test_us
AssertionError
>>>
基本上,assert关键字的含义是,如果条件不成立,则通过assertionerror进行处理,否则例如在python中继续进行。
代码1
a=5
b=6
assert a==b
输出:
assert a==b
AssertionError
代码2
a=5
b=5
assert a==b
输出:
Process finished with exit code 0
assert
,但没有回答何时使用(或不使用)assert
。