Chapter 27
Exception Basics
本书最后一个Python的主要内容,关于异常处理
与异常相关的关键字
1:try/except //与Java类似,新特性:同时捕获多个异常
2:try/finally //与Java类似
3:raise //与Java中的throw类似
4:assert //断言
5:with/as //未知
同样也可以使用常见的else语句,将会在没有异常抛出时执行
常见的语法格式
Clause form Interpretation
except: Catch all (other) exception types.
except name: Catch a specific exception only.
except name, value: Catch the listed exception and its extra data (or instance).
except (name1, name2): Catch any of the listed exceptions.
except (name1, name2), value: Catch any of the listed exceptions, and get its extra data.
else: Run if no exceptions are raised.
finally: Always perform this block.
如果没有使用catch块捕获,那么将会抛出系统默认的异常,导致程序结束
和Java一样,建议使用finally执行内存的回收
使用else的时候,需要注意else需要在finally之前
raise,用于抛出异常,常见格式如下
raise <name> # Manually trigger an exception
raise <name>, <data> # Pass extra data to catcher too
raise # Re-raise the most recent exception
可以任意定义一个class,然后使用raise class() 就可以抛出,使用except class: 进行捕获
可以使用 raise Error,'..' 抛出异常信息,在except时,同时进行捕获
_ _debug_ _ 内置函数,用于在编译器中设置,切换1-0.用于在测试代码中表示是否执行逻辑判断
if _ _debug_ _:
if not <test>:
raise AssertionError, <data>
也可以使用assert断言,来进行判断表达式是否成立,然后外带一个字符串进行抛出异常信息,异常
类型为AssertionError
assert x < 0, 'x must be negative'
注意assert常用于定义限制用户输入条件等情况下,而不需要去判断数组越界的Python内置异常能够判断的
情况
with/as 2.6中正式提供,在2.5中需要手动的import
from _ _future_ _ import with_statement
常用于资源的自动回收,类似try--finally //Groovy中也有类似的实现
常见格式
with expression [as variable]:
with-block
如
文件读取
with open(r'C:\python\scripts') as myfile:
...
线程锁定
lock = threading.Lock( )
with lock:
自定义类 支持Context Management 协议 (with/as)的使用
1:需要实现__enter__ 和 __exit__方法
2:__enter__方法被调用后,只要返回self就好
3:必须嵌套在block块内
4:如果with块中抛出了一个异常,__exit__(type, value, traceback) 方法将会接受到一个异常
的信息详情
5:如果没有抛出异常,exit方法的type, value, and traceback 将会是None
class TraceBlock:
def message(self, arg):
print 'running', arg
def _ _enter_ _(self):
print 'starting with block'
return self
def _ _exit_ _(self, exc_type, exc_value, exc_tb):
if exc_type is None:
print 'exited normally\n'
else:
print 'raise an exception!', exc_type
return False # propagate
使用的方法
with TraceBlock( ) as action:
action.message('test 1')
print 'reached'
__exit__返回如果是false,表示将会再次抛出异常,true则不会,但都会导致后续代码不会执行,
可以使用try--catch..来避免
使用异常来处理,而不是用返回值进行重复劳动
凑字数问题..
Chapter Quiz
1. What is the try statement for?
2. What are the two common variations of the try statement?
3. What is the raise statement for?
4. What is the assert statement designed to do, and what other statement is it like?
5. What is the with/as statement designed to do, and what other statement is it
like?
Quiz Answers
1. The try statement catches and recovers from exceptions—it specifies a block of
code to run, and one or more handlers for exceptions that may be raised during
the block’s execution.
2. The two common variations on the try statement are try/except/else (for catching
exceptions), and try/finally (for specifying cleanup actions that must occur
whether an exception is raised or not). In Python 2.4, these are separate statements
that can be combined by syntactic nesting; in 2.5 and later, except and
finally blocks may be mixed in the same statement, so the two statement forms
are merged. In the merged form, the finally is still run on the way out of the
try, regardless of what exceptions may have been raised or handled.
3. The raise statement raises (triggers) an exception. Python raises built-in exceptions
on errors internally, but your scripts can trigger built-in or user-defined
exceptions with raise, too.
4. The assert statement raises an AssertionError exception if a condition is false. It
works like a conditional raise statement wrapped up in an if statement.
5. The with/as statement is designed to automate startup and termination activities
that must occur around a block of code. It is roughly like a try/finally
statement in that its exit actions run whether an exception occurred or not, but
it allows a richer object-based protocol for specifying entry and exit actions.
Chapter 28
Exception Objects
异常对象
同时可以使用str对象和class对象 raise异常,不过更推荐使用class为异常,便于管理和使用
// 注意 也许只有2.5中可以使用str 作为异常raise
sys.exc_info( )[0] 可以用于捕获最近的异常信息
类异常中,如果抛出的异常是子类,将会被父类捕获,与Java相同
可以使用
except (General, Specific1, Specific2):
用于具体捕获子类与父类,然后使用sys.exc_info( )[0] 来查看异常的具体类型
为了将来代码升级顺利,建议使用Exception为异常的super class
可以 import exceptions,后通过help查看Python内置异常的详细信息
可以使用StandardError: except捕获所有的内置异常类型
异常抛出时,将会调用调用异常类的__repr__ or __str__方法,可以通过重写达到记录详细信息的目的
如果继承自Exception类,可以通过带构造函数传入参数,将会在异常信息中打印出
raise MyBad('the', 'bright', 'side', 'of', 'life')
自定义异常类的构造函数 __init__, 传入参数后,在raise时进行捕获
import sys
class db():
def __init__(self,X,Y):
self.x=X
self.y=Y
def c():
raise db(1,3)
try:
c()
except db,db1:
print 'catch db',db1.x,db1.y
使用 第二个参数进行对象的捕获和获取异常信息
用法一,通过传递过来的异常对象,调用对应的内置异常日志方法
也可以使用raise 异常类型,任意类型, 来传递指定的信息
如: raise formatError, {'line':42, 'file':'spam.txt'}
raise不能传递序列,不过可以通过自定义异常对象进行传递
一些其他raise格式 与class相关,都会自动生成一个实例
raise class # Same as: raise class( )
raise class, arg # Same as: raise class(arg)
raise class, (arg, arg, ...) # Same as: raise class(arg, arg, ...) //类似作为class实例的构造函数
raise KeyError( ) # Normal form: raise an instance
raise KeyError, KeyError( ) # Class, instance: use instance
raise KeyError # Class: an instance will be generated
raise KeyError, "bad spam" # Class, arg: an instance will be generated
凑字数问题省略
Chapter 29
Designing with Exceptions
sys.exc_info 下的格式为(type, value, traceback)的tuple
应该使用try---except进行包装的地方
1:与系统相关的操作,如文件打开,socket使用
2:避免使用空的(Aviod) except
3:可以将多个try..块合并到一起
本书结束..附录也是相当精彩,有条件的也可以看下
Exception Basics
本书最后一个Python的主要内容,关于异常处理
与异常相关的关键字
1:try/except //与Java类似,新特性:同时捕获多个异常
2:try/finally //与Java类似
3:raise //与Java中的throw类似
4:assert //断言
5:with/as //未知
同样也可以使用常见的else语句,将会在没有异常抛出时执行
常见的语法格式
Clause form Interpretation
except: Catch all (other) exception types.
except name: Catch a specific exception only.
except name, value: Catch the listed exception and its extra data (or instance).
except (name1, name2): Catch any of the listed exceptions.
except (name1, name2), value: Catch any of the listed exceptions, and get its extra data.
else: Run if no exceptions are raised.
finally: Always perform this block.
如果没有使用catch块捕获,那么将会抛出系统默认的异常,导致程序结束
和Java一样,建议使用finally执行内存的回收
使用else的时候,需要注意else需要在finally之前
raise,用于抛出异常,常见格式如下
raise <name> # Manually trigger an exception
raise <name>, <data> # Pass extra data to catcher too
raise # Re-raise the most recent exception
可以任意定义一个class,然后使用raise class() 就可以抛出,使用except class: 进行捕获
可以使用 raise Error,'..' 抛出异常信息,在except时,同时进行捕获
_ _debug_ _ 内置函数,用于在编译器中设置,切换1-0.用于在测试代码中表示是否执行逻辑判断
if _ _debug_ _:
if not <test>:
raise AssertionError, <data>
也可以使用assert断言,来进行判断表达式是否成立,然后外带一个字符串进行抛出异常信息,异常
类型为AssertionError
assert x < 0, 'x must be negative'
注意assert常用于定义限制用户输入条件等情况下,而不需要去判断数组越界的Python内置异常能够判断的
情况
with/as 2.6中正式提供,在2.5中需要手动的import
from _ _future_ _ import with_statement
常用于资源的自动回收,类似try--finally //Groovy中也有类似的实现
常见格式
with expression [as variable]:
with-block
如
文件读取
with open(r'C:\python\scripts') as myfile:
...
线程锁定
lock = threading.Lock( )
with lock:
自定义类 支持Context Management 协议 (with/as)的使用
1:需要实现__enter__ 和 __exit__方法
2:__enter__方法被调用后,只要返回self就好
3:必须嵌套在block块内
4:如果with块中抛出了一个异常,__exit__(type, value, traceback) 方法将会接受到一个异常
的信息详情
5:如果没有抛出异常,exit方法的type, value, and traceback 将会是None
class TraceBlock:
def message(self, arg):
print 'running', arg
def _ _enter_ _(self):
print 'starting with block'
return self
def _ _exit_ _(self, exc_type, exc_value, exc_tb):
if exc_type is None:
print 'exited normally\n'
else:
print 'raise an exception!', exc_type
return False # propagate
使用的方法
with TraceBlock( ) as action:
action.message('test 1')
print 'reached'
__exit__返回如果是false,表示将会再次抛出异常,true则不会,但都会导致后续代码不会执行,
可以使用try--catch..来避免
使用异常来处理,而不是用返回值进行重复劳动
凑字数问题..
Chapter Quiz
1. What is the try statement for?
2. What are the two common variations of the try statement?
3. What is the raise statement for?
4. What is the assert statement designed to do, and what other statement is it like?
5. What is the with/as statement designed to do, and what other statement is it
like?
Quiz Answers
1. The try statement catches and recovers from exceptions—it specifies a block of
code to run, and one or more handlers for exceptions that may be raised during
the block’s execution.
2. The two common variations on the try statement are try/except/else (for catching
exceptions), and try/finally (for specifying cleanup actions that must occur
whether an exception is raised or not). In Python 2.4, these are separate statements
that can be combined by syntactic nesting; in 2.5 and later, except and
finally blocks may be mixed in the same statement, so the two statement forms
are merged. In the merged form, the finally is still run on the way out of the
try, regardless of what exceptions may have been raised or handled.
3. The raise statement raises (triggers) an exception. Python raises built-in exceptions
on errors internally, but your scripts can trigger built-in or user-defined
exceptions with raise, too.
4. The assert statement raises an AssertionError exception if a condition is false. It
works like a conditional raise statement wrapped up in an if statement.
5. The with/as statement is designed to automate startup and termination activities
that must occur around a block of code. It is roughly like a try/finally
statement in that its exit actions run whether an exception occurred or not, but
it allows a richer object-based protocol for specifying entry and exit actions.
Chapter 28
Exception Objects
异常对象
同时可以使用str对象和class对象 raise异常,不过更推荐使用class为异常,便于管理和使用
// 注意 也许只有2.5中可以使用str 作为异常raise
sys.exc_info( )[0] 可以用于捕获最近的异常信息
类异常中,如果抛出的异常是子类,将会被父类捕获,与Java相同
可以使用
except (General, Specific1, Specific2):
用于具体捕获子类与父类,然后使用sys.exc_info( )[0] 来查看异常的具体类型
为了将来代码升级顺利,建议使用Exception为异常的super class
可以 import exceptions,后通过help查看Python内置异常的详细信息
可以使用StandardError: except捕获所有的内置异常类型
异常抛出时,将会调用调用异常类的__repr__ or __str__方法,可以通过重写达到记录详细信息的目的
如果继承自Exception类,可以通过带构造函数传入参数,将会在异常信息中打印出
raise MyBad('the', 'bright', 'side', 'of', 'life')
自定义异常类的构造函数 __init__, 传入参数后,在raise时进行捕获
import sys
class db():
def __init__(self,X,Y):
self.x=X
self.y=Y
def c():
raise db(1,3)
try:
c()
except db,db1:
print 'catch db',db1.x,db1.y
使用 第二个参数进行对象的捕获和获取异常信息
用法一,通过传递过来的异常对象,调用对应的内置异常日志方法
也可以使用raise 异常类型,任意类型, 来传递指定的信息
如: raise formatError, {'line':42, 'file':'spam.txt'}
raise不能传递序列,不过可以通过自定义异常对象进行传递
一些其他raise格式 与class相关,都会自动生成一个实例
raise class # Same as: raise class( )
raise class, arg # Same as: raise class(arg)
raise class, (arg, arg, ...) # Same as: raise class(arg, arg, ...) //类似作为class实例的构造函数
raise KeyError( ) # Normal form: raise an instance
raise KeyError, KeyError( ) # Class, instance: use instance
raise KeyError # Class: an instance will be generated
raise KeyError, "bad spam" # Class, arg: an instance will be generated
凑字数问题省略
Chapter 29
Designing with Exceptions
sys.exc_info 下的格式为(type, value, traceback)的tuple
应该使用try---except进行包装的地方
1:与系统相关的操作,如文件打开,socket使用
2:避免使用空的(Aviod) except
3:可以将多个try..块合并到一起
本书结束..附录也是相当精彩,有条件的也可以看下