我已经学习了一段时间的Python而且raise
函数和assert
是(我意识到他们都崩溃了应用程序,不像尝试 - 除外)真的很相似,我可以&# 39;看到您使用raise
或assert
而不是try
的情况。
那么,Raise,Try和Assert之间有什么区别?
答案 0 :(得分:25)
断言:
当您想要"停止&#34>时使用基于某种条件的脚本并返回一些东西来帮助调试更快:
list_ = ["a","b","x"]
assert "x" in list_, "x is not in the list"
print("passed")
#>> prints passed
list_ = ["a","b","c"]
assert "x" in list_, "x is not in the list"
print("passed")
#>>
Traceback (most recent call last):
File "python", line 2, in <module>
AssertionError: x is not in the list
抬起:
对此有用的两个原因:
1 /与try和except块一起使用。提出您选择的错误,可以像下面一样自定义,如果您pass
或contiune
脚本,则不会停止脚本;或者可以是预定义的错误raise ValueError()
class Custom_error(BaseException):
pass
try:
print("hello")
raise Custom_error
print("world")
except Custom_error:
print("found it not stopping now")
print("im outside")
>> hello
>> found it not stopping now
>> im outside
注意到它没有停止?我们可以使用except块中的exit(1)来停止它。
2 / Raise也可用于重新加载当前错误以将其传递到堆栈以查看是否有其他东西可以处理它。
except SomeError, e:
if not can_handle(e):
raise
someone_take_care_of_it(e)
尝试/除了块:
完全符合您的想法,尝试一些事情,如果出现错误,您可以抓住它并按照您喜欢的方式处理它。没有例子,因为上面有一个。
答案 1 :(得分:22)
assert cond, "text"
扩展为类似
if cond == False:
raise AssertionError("text")
使用assert因为它更具可读性。
答案 2 :(得分:17)
raise
- 提出异常。
assert
- 如果某个特定条件(或者不是真),则引发异常。
try
- 执行一些可能引发异常的代码,如果是,请抓住它。
答案 3 :(得分:9)
try/except
块可让您捕获和管理异常。 raise
,assert
和大量错误(例如尝试索引空列表)可能会触发异常。检测到错误情况时,通常会使用raise
。 assert
类似,但仅在满足条件时才会引发异常。
raise
和assert
有不同的理念。您检测到的代码中存在许多“正常”错误并引发错误。也许网站不存在或参数值超出范围。
断言通常保留为“我发誓这不可能发生”的问题,无论如何都会发生。它更像是运行时调试而不是正常运行时错误检测。如果您使用-O
标志或从.pyo
文件而不是.pyc
文件运行,则可以禁用断言,因此它们不应成为常规错误检测的一部分。
如果生产质量代码引发异常,那么弄清楚你做错了什么。如果它提出AssertionError
,你就会遇到更大的问题。
答案 4 :(得分:2)
assert
和raise AssertionError
之间没有区别,它们将编译为完全相同的字节码:
import dis
def foo1(param):
assert param, "fail"
def foo2(param):
if not param:
raise AssertionError("fail")
print(dis.dis(foo1))
print(dis.dis(foo2))
输出:
4 0 LOAD_FAST 0 (param) 2 POP_JUMP_IF_TRUE 12 4 LOAD_GLOBAL 0 (AssertionError) 6 LOAD_CONST 1 ('fail') 8 CALL_FUNCTION 1 10 RAISE_VARARGS 1 >> 12 LOAD_CONST 0 (None) 14 RETURN_VALUE None 7 0 LOAD_FAST 0 (param) 2 POP_JUMP_IF_TRUE 12 8 4 LOAD_GLOBAL 0 (AssertionError) 6 LOAD_CONST 1 ('fail') 8 CALL_FUNCTION 1 10 RAISE_VARARGS 1 >> 12 LOAD_CONST 0 (None) 14 RETURN_VALUE None
答案 5 :(得分:1)
异常是Python(和其他一些语言)用来处理执行代码时出现的错误的原因。 raise ExceptionName
表示代码中存在错误,并通过引发与该问题相关的异常来指定它是什么类型的问题。 assert expression
评估expression
并在错误时引发异常。
try
用于执行可能引发您期望的异常的代码。你可以“赶上”#34;而不是停止计划。异常并在您的代码中处理它。
示例:假设您有字典和列表。你希望从字典中的列表中查找内容,直到找到字典中没有的内容:
try:
for item in my_list:
print(my_dictionary[item])
except KeyError as e: #KeyError is the Exception raised when a key is not in a dictionary
print('There is no {} in the dictionary'.format(e.args[0]))
答案 6 :(得分:1)
断言通常用于测试代码以确保某些工作正常:
def test_bool():
assert True != False
尝试的时候,提高和除了化妆异常处理,这是python处理和传播错误的首选方法。
如果出现问题,大多数库和python内置函数都会引发一种或另一种类型的异常。通常在您自己的代码中,您还需要在检测到出错时引发异常。让我们举个例子说你正在编写一个电子邮件地址验证器,如果地址没有包含@符号,你想提出异常。你可能有类似的东西(这是玩具代码,实际上并不是这样验证电子邮件):
def validate_email(address):
if not "@" in address:
raise ValueError("Email Addresses must contain @ sign")
然后在代码中的其他地方你可以调用validate_email函数,如果失败则会抛出异常。
try:
validate_email("Mynameisjoe.com")
except ValueError as ex:
print("We can do some special invalid input handling here, Like ask the user to retry the input")
finally:
close_my_connection()
print("Finally always runs whether we succeed or not. Good for clean up like shutting things down.")
要知道的重要一点是,当引发异常时,它会在调用堆栈中向上传递,直到找到一个处理程序。如果它从未找到处理程序,那么它将使程序崩溃,异常和堆栈跟踪。
你不想做的一件事是:
if __name__ == '__main__':
try:
print(1/0)
except Exception as ex:
pass
现在你无法知道为什么你的应用程序爆炸了。
你经常会看到一件好事就是:
import logging
if __name__ == '__main__':
try:
print(1/0)
except Exception as ex:
logging.exception(ex)
raise
在这种情况下加注,因为它没有参数重新引发相同的错误。通常在Web代码中,您会看到类似的东西,不会重新引发异常,因为它会向客户端发送500错误,然后继续下一个请求,因此在这种情况下,您不希望程序端。
答案 7 :(得分:1)
断言
语法:assert_stmt ::= "assert" expression1 ["," expression2]
在执行时会翻译为:
if __debug__:
if not expression1:
raise AssertionError(expression2)
__debug__
是一个内置标志,通常为true,但是如果触发了优化,则它将为false,因此断言将是无效代码=>在启动Python时使用-O和-OO标志禁用(或CPython中的PYTHONOPTIMIZE env变量),因此,请勿依赖于它们的代码逻辑。assert (<some_test>, 'warn string')
= >注意元组构造(错误!)检查:Catching bogus Python asserts on CI by Dan Bader
引发/例外
尝试
顺便说一句,我强烈推荐Dan Bader的这本书"Python Tricks: The Book"(来自realpython.com)
答案 8 :(得分:0)
另一个answers很好地解释了这些差异,但是许多人都没有提到使用-O优化器标志时assert
语句将被忽略。
一个获得与assert
相似的简洁语法的选项,使-O在使用时仍使异常生效,并且能够引发特定异常类型的好处是定义了这样的实用函数:
def raiseif(cond, msg="", exc=AssertionError):
if cond:
raise exc(msg)
raiseif(x != y, "x should equal y")
该逻辑与assert
相反,但是您可以根据需要轻松更改。
答案 9 :(得分:0)
raise
用于引发异常; assert
用于在给定条件为False
的情况下引发异常。