印象回溯
示例1:直至用户输入一个合法数字,打印并退出。
while True: try: num = int(raw_input("Please enter a number: ")) except ValueError,e: print e else: print num break
执行结果:
Please enter a number: sjf invalid literal for int() with base 10: 'sjf' #抛出异常,e Please enter a number: 213 213 Process finished with exit code 0
ps:先执行try:...下的主体程序,如果有异常则执行except,没有异常就接着执行else下的语句。
示例2:try...except...else...finally
import logging # 配置日志信息 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M', filename='myapp.log', filemode='w') # 定义一个Handler打印INFO及以上级别的日志到sys.stderr console = logging.StreamHandler() console.setLevel(logging.INFO) # 设置日志打印格式 formatter = logging.Formatter('%(asctime)-25s %(name)-6s:%(levelname)-8s%(message)s') console.setFormatter(formatter) # 将定义好的console日志handler添加到root logger logging.getLogger('').addHandler(console) try: f = open(fileName) except IOError,e: logging.error(e) else: pass logging.info("Open sucess!") e = False finally: if e: pass else: f.close()
文件存在,正确打开:
2017-06-04 23:42:10,367 root :INFO Open sucess!
文件不存在,IOerror异常:
2017-06-04 23:49:33,535 root :ERROR [Errno 2] No such file or directory: 'dd' Process finished with exit code 0
ps:上面例子是打开一个文件的操作,顺便引入了日志输出。文件存在,无异常抛出,不执行except,执行else下操作,可以对文件内容进行遍历等,然后记录日志成功打开并处理ok。这里我设置了一个标志位,主要是为了判定文件是否成功打开,若有异常抛出,则e有值为True,表示文件没有成功打开,也就不需要关闭文件句柄,直接pass不做任何操作,反之无异常,将e置为False,执行f.close关闭文件
进阶
示例1:自定义异常
class MyError(Exception): def __init__(self,msg = None): self.msg = msg def __str__(self): if self.msg: return self.msg else: return "Nothing important" try: raise MyError() except Exception,e: print e
ps:以下为python中exceptions派生类与基类关系一览表
BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StandardError | +-- BufferError | +-- ArithmeticError | | +-- FloatingPointError | | +-- OverflowError | | +-- ZeroDivisionError | +-- AssertionError | +-- AttributeError | +-- EnvironmentError | | +-- IOError | | +-- OSError | | +-- WindowsError (Windows) | | +-- VMSError (VMS) | +-- EOFError | +-- ImportError | +-- LookupError | | +-- IndexError | | +-- KeyError | +-- MemoryError | +-- NameError | | +-- UnboundLocalError | +-- ReferenceError | +-- RuntimeError | | +-- NotImplementedError | +-- SyntaxError | | +-- IndentationError | | +-- TabError | +-- SystemError | +-- TypeError | +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning
- 我们可以看到,常见异常如:NameError,TypeError,ValueError...等都是Exception类的派生类,因此我们自定义类也以Exception为基类。
- __str__(self):可打印字符串表示:如str()就有该内置方法。
- raise:主动抛出异常,然后用except捕获
- MyError()可自定义异常信息,如:raise MyError("Test!");否则默认输出"Nothing important"
示例2:断言:条件成立,继续执行;条件不成立,抛出异常
>>> assert 1==1;print("pass") pass >>> assert 1==2;print("pass") Traceback (most recent call last): File "<pyshell#1>", line 1, in <module> assert 1==2;print("pass") AssertionError
就这么用!!
try: #执行主体 pass except Exception,e: #有异常,执行该语句体 pass else: #主体执行完后,执行该语句体 pass finally: #无论是否有异常,最终都执行该语句体 pass