http://blog.csdn.net/pipisorry/article/details/21841883html
断言是一句必须等价于布尔真的断定;此外,发生异常也意味着表达式为假.这些工做相似于 C 语言预处理器中 assert 宏,但在 Python 中它们在运行时构建(与之相对的是编译期判别).
若是你刚刚接触断言这个概念,无妨.断言能够简简单单的想象为 raise-if 语句(更准确的说是raise-if-not 语句).测试一个表达式,若是返回值是假,触发异常.python
断言语句等价于这样的 Python 表达式,若是断言成功不采起任何措施(相似语句),不然触发AssertionError(断言错误)的异常.assert 的语法以下:
assert expression[, arguments]数据库
示例assert mode in ["train", "eval", "inference"],若是输入的mode不在其中则触发异常express
[Python中什么时候使用断言]编程
最重要的问题是你在开发过程当中隐藏了bug,若是当时你没加这个Try…Catch,恐怕你早就发现这个bug了,由于程序压根就跑不下去。segmentfault
[try catch 对代码运行的性能影响]socket
(含py2和py3的区别)函数
Python 3
try:性能
...
except Exception as e:
print(e)
不过lz推荐下面的格式:
import traceback
try:
...
except:
print(traceback.format_exc())
input("hold on...")
直接调用print Exception, e获得的结果就只有一行信息,只是异常的名字和说明而已。而这样能够输出栈信息,ide中点击就能够到达错误位置,而且不会一闪而过。
1)因此异常都从 BaseException继承,并删除了StardardError 。StandardError
异常:在Python 2里,StandardError
是除了StopIteration
,GeneratorExit
,KeyboardInterrupt
,SystemExit
以外全部其余内置异常的基类。在Python 3里,StandardError
已经被取消了;使用Exception
替代。
Notes | Python 2 | Python 3 |
---|---|---|
x =StandardError() |
x =Exception() |
|
x =StandardError(a, b, c) |
x =Exception(a, b, c) |
2)去除了异常类的序列行为和.message属性
3)异常链,由于__context__在3.0a1版本中没有实现
as
。as
也能够用在一次捕获多种类型异常的状况下。在导入模块(或者其余大多数状况)的时候,你绝对不该该使用这种方法(指以上的fallback)。否则的话,程序可能会捕获到像KeyboardInterrupt
(若是用户按Ctrl-C来中断程序)这样的异常,从而使调试变得更加困难。
Python 3里,抛出自定义异常的语法有细微的变化。
Notes | Python 2 | Python 3 |
---|---|---|
① | raise MyException |
unchanged |
② | raise MyException,'error message' |
raise MyException('error message') |
③ | raise MyException,'error message', a_traceback |
raise MyException('error message').with_traceback(a_traceback) |
④ | raise 'error message' |
unsupported |
Note:
2to3
将会警告你它不能自动修复这种语法。How can I write a lambda expression that's equivalent to:
def x():
raise Exception()
The following is not allowed:
y = lambda : raise Exception()
lambda errmsg: exec('raise(Exception(errmsg))')
[Define a lambda expression that raises an Exception]
在Python 2里,生成器有一个throw()
方法。调用a_generator.throw()
会在生成器被暂停的时候抛出一个异常,而后返回由生成器函数获取的下一个值。在Python 3里,这种功能仍然可用,可是语法上有一点不一样。
Notes | Python 2 | Python 3 |
---|---|---|
① | a_generator.throw(MyException) |
no change |
② | a_generator.throw(MyException,'error message') |
a_generator.throw(MyException('error message')) |
③ | a_generator.throw('error message') |
unsupported |
2to3
会显示一个警告信息,告诉你须要手动地来修复这处代码。Python 3中的异常处理也发生了一点变化。在Python 3中必须使用“as”关键字。
Python 2
try:
let_us_cause_a_NameError
except NameError, err:
print err, '--> our error message'
name 'let_us_cause_a_NameError' is not defined --> our error message
Python 3
try:
let_us_cause_a_NameError
except NameError as err:
print(err, '--> our error message')
name 'let_us_cause_a_NameError' is not defined --> our error message
except的一个例子:
考虑下面这个文件
import sys def bar(i): if i == 1: raise KeyError(1) def bad(): e = None try: bar(int(sys.argv[1])) except KeyError as e: print('key error') print(e) bad()
在python2中一切运做正常
$ python foo.py 1
key error 1
可是在python3中事情变得一团糟
$ python3 foo.py 1
key error
Traceback (most recent call last):
File "foo.py", line 19, in <module> bad() File "foo.py", line 17, in bad print(e) UnboundLocalError: local variable 'e' referenced before assignment
Note:问题出在,在Python3中,异常对象没法在异常块做用域外访问。(缘由是在垃圾收集器运行且从内存中清理引用以前会在内存栈帧中保存一个引用周期)
解决此问题的方法之一是在异常块做用域外围护一个异常对象的引用,以使其可访问。这里是前例使用这一技术的一个版本,使得代码对Python2和Python3都友好:
import sys
def bar(i): if i == 1: raise KeyError(1) def good(): exception = None try: bar(int(sys.argv[1])) except KeyError as e: exception = e print('key error') print(exception)
如今除以变量A=0都不会被try-except捕捉到了,会直接在运行时警告:
RuntimeWarning: divide by zero encountered in double_scalars
只有直接除以0才会被try-except捕捉到
x,y为字典,若是x < y的不能比较,抛出TypeError异常。2.x版本是返回伪随机布尔值的。
处理异常的时候,在sys模块里有三个你能够访问的变量:sys.exc_type,sys.exc_value,sys.exc_traceback。(实际上这些在Python 1的时代就有。)从Python 1.5开始,因为新出的sys.exc_info,再也不推荐使用这三个变量了,这是一个包含全部以上三个元素的元组。在Python 3里,这三个变量终于再也不存在了;这意味着,你必须使用sys.exc_info。
Notes | Python 2 | Python 3 |
---|---|---|
sys.exc_type | sys.exc_info()[0] | |
sys.exc_value | sys.exc_info()[1] | |
sys.exc_traceback | sys.exc_info()[2] |
[python上下文管理器ContextLib及with语句]
在异常处理语句中,当try代码块没有抛出任何的异常时,else语句块会被执行到。
def my_to_int(str_param):
try:
print int(str_param)
except ValueError:
print 'cannot convert {} to a integer'.format(str_param)
else:
print 'convert {} to integer successfully'.format(str_param)
my_to_int("123")
my_to_int("me123")
convert 123 to integer successfully
cannot convert me123 to a integer
如打印日志所示,在转换成功未发生错的的时候,else语句里的逻辑会被执行,固然这个例子可能并无什么太多的实际的用处,但大体能说明else在错误处理中的用处:简化逻辑,避免使用一些标志值就可以准确把握是否发生错误的状况来作一些实际的操做(好比在保存数据的时候若是发生错误,在else语句块中进行rollback的操做,而后紧接着还能加上finally语句完成一些清理操做。
Exceptions做为一种控制结构,在处理数据库、sockets、文件或者任何可能失败的资源时很是经常使用。使用标准的 try 、except 结构写数据库操做时一般是类型这样的方式。
try:
# get API data
data = db.find(id='foo') # may raise exception
# manipulate the data
db.add(data)
# save it again
db.commit() # may raise exception
except Exception:
# log the failure
db.rollback()
db.close()
你能发现这里的问题吗?这里有两种可能的异常会触发相同的except模块。这意味着查找数据失败(或者为查询数据创建链接失败)会引起回退操做。这绝对不是咱们想要的,由于在这个时间点上事务并无开始。一样回退也不该该是数据库链接失败的正确响应,所以让咱们将不一样的状况分开处理。
首先,咱们将处理查询数据。
try:
# get API data
data = db.find(id='foo') # may raise exception
except Exception:
# log the failure and bail out
log.warn("Could not retrieve FOO")
return
# manipulate the data
db.add(data)
如今数据检索拥有本身的try-except,这样当咱们没有取得数据时,咱们能够采起任何处理方式。没有数据咱们的代码不大可能再作有用的事,所以咱们将仅仅退出函数。除了退出你也能够构造一个默认对象,从新进行检索或者结束整个程序。
如今让咱们将commit的代码也单独包起来,这样它也能更优雅的进行错误处理。
try:
db.commit() # may raise exception
except Exception:
log.warn("Failure committing transaction, rolling back")
db.rollback()
else:
log.info("Saved the new FOO")
finally:
db.close()
实际上,咱们已经增长了两端代码。首先,让咱们看看else,当没有异常发生时会执行这里的代码。在咱们的例子中,这里只是将事务成功的信息写入日志,可是你能够按照须要进行更多有趣的操做。一种可能的应用是启动后台任务或者通知。
很明显finally 子句在这里的做用是保证db.close() 老是可以运行。回顾一下,咱们能够看到全部和数据存储相关的代码最终都在相同的缩进级别中造成了漂亮的逻辑分组。之后须要进行代码维护时,将很直观的看出这几行代码都是用于完成 commit操做的。
常见的python异常类型
from:http://blog.csdn.net/pipisorry/article/details/21841883