首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python异常捕获与抛出以及With语句简介

Python3使用try ... except [else]来捕获异常,且要求异常必须继承Exception类。所有Built-in异常都继承自这个类。

捕获异常

使用 sys.exc_info 和 sys.last_traceback(包含的内容与 sys.exc_info() 相同,但它主要用于调试)可获取异常的详细信息,会返回一个3值元表(type, value, traceback) ,其中:

type:捕获到异常的类型名称;

value:捕获到异常的实例;

traceback:是一个包含stack traceback的对象;可通过traceback模块打印出来:

traceback.print_exc():直接打印当前异常信息;

traceback.print_tb(...):打印traceback对象信息;

traceback.print_exception(*sys.exc_info()):直接打印元素;

try:

...

raise

except ValueError as err:

print("Value error: ".format(err))

except Exception:

print(err)

t,v,tb = sys.exc_info()

traceback.print_tb(tb)

else: #except可以有多个,但else必须在最后

[...没有异常时]

finally:

[...总是执行]

一个except中捕获多个异常:

except (RuntimeError, TypeError, NameError):

抛出异常

可通过raise抛出build-in异常,也可自定义异常(要直接或间接继承自Exception):

class MyError(Exception):

def __init__(self, value):

self.value = value

def __str__(self):

return repr(self.value)

try:

raise MyError(2*2)

except MyError as e:

print('My exception occurred, value:', e.value)

预定义清理行为with

with语句用于保证任何情况下(包括抛出异常时)都能对当前进行访问的资源进行必要的清理工作。

对象要支持with需要满足上下文管理协议:

__enter__(self):语句体执行前调用执行,进入与此对象相关的运行时上下文;with语句将将此方法的返回值绑定到语句的AS子句中指定的目标(如果有设置的话);

__exit__(self, exc_type, exc_value, traceback):语句体执行完成,退出上下文时执行;

参数描述导致上下文退出的异常。如果上下文运行时没有异常发生,那么三个参数都将置为None。

如果有异常发生,并且该方法希望抑制异常(即阻止它被传播),则它应该返回True。否则,异常将在退出该方法时正常处理。

with context-expression [as target]:

with-body

文件访问完成后,总是保证文件被正确关闭了

with open(r'mytest') as tfile:

for line in tfile:

print(line)

一个简单示例:

class DummyResource:

def __init__(self, tag):

self.tag = tag

print('Resource [%s]' % tag)

def __enter__(self):

print('[Enter %s]: Allocate resource.' % self.tag)

return self # 可以返回不同的对象

def __exit__(self, exc_type, exc_value, exc_tb): #无异常时,后三个参数都为None

if exc_tb is None:

print('[Exit %s]: Exited without exception.' % self.tag)

return True

else:

print('[Exit %s]: Exited with exception raised.' % self.tag)

return False # 可以省略,缺省的None也是被看做是False

with DummyResource("test") as dr:

print(dr)

@contextmanager

编写 __enter__ 和 __exit__ 仍然很繁琐,因此Python的标准库 contextlib 提供了更简单的写法:

from contextlib import contextmanager

class Query(object):

def __init__(self, name):

self.name = name

def query(self):

print('Query info about %s...' % self.name)

@contextmanager

def create_query(name):

print('Begin')

q = Query(name)

yield q

print('End')

这个装饰器接受一个generator,用yield语句把 with ... as var 把变量输出出去,然后with 语句就可以正常的工作了:

with create_query('Bob') as q:

q.query()

很多时候,我们希望在某段代码执行前后自动执行特定代码,也可以用 @contextmanager实现。

@contextmanager

def tag(name):

print("" % name)

yield

print("" % name)

with tag("h1"):

print("hello")

print("world")

代码的执行顺序是:

with 语句 首先执行 yield 之前的语句,因此打印出 .

yield 调用会执行 with 语句内部的所有语句,因此打印出 hello 和 world.

最后执行yield之后的语句,打印出 .

@closing

如果一个对象没有实现上下文,就不能使用 with 语句,但是可以用 closing() 来把对象变为上下文对象。

from contextlib import closing

from urllib.request import urlopen

with closing(urlopen('https://www.python.org')) as page:

for line in page:

print(line)

closing 也是一个经过 @contextmanager 装饰的generator

@contextmanager

def closing(thing):

try:

yield thing

finally:

thing.close()

它的作用就是把任意对象变为上下文对象,并支持 with语句。

常见异常

- BaseException # 所有异常的父类

- SystemExit # 由sys.exit()抛出的异常

- KeyBoardInterrupt # 通常由ctrl+c或者Delete抛出的异常

- GeneratorExit # 当生成器被关闭时抛出的异常

- Exception #

- StopIteration # 迭代结束异常

- StopAsyncIteration # 由异步迭代的`__anext__()`抛出的异常

- ArithmeticError # 各种算数错误引起的异常

- FloatingPointError # 浮点数操作错误

- OverflowError # 结果超出范围

- ZeroDivisionError # 0为除数异常

- AssertionError # assert错误异常

- AttributeError # 属性引用异常

- BufferError # 缓存错误

- EOFError # 读不到数据

- ImportError # import错误

- ModuleNotFoundError # 找不多模块

- LookupError # 由索引和key值引起的异常

- IndexError # 索引错误

- KeyError # 字典key值错误

- MemoryError # 内存溢出异常

- NameError # 本地和全局找不到变量名

- UnboundLocalError # 局部变量没有赋值

- OSError # system错误

- BlockingIOError # 调用阻塞异常错误

- ChildProcessError # 子进程

- ConnectionError # 连接

- BrokenPipeError # 管道读写异常

- ConnectionAbortedError # 连接失败

- ConnectionRefusedError # 连接拒绝

- ConnectionResetError # 连接重置

- FileExistsError # 创建文件和文件夹错误

- FileNotFoundError # 文件未找到

- InterruptedError # 中断错误

- IsADirectoryError # 文件操作用在文件夹上

- NotADirectoryError # 不是文件夹

- PermissionError # 权限

- ProcessLookupError # 进程不存在

- TimeoutError # 超时

- ReferenceError # 引用异常

- RuntimeError #

- NotImplementedError # 运行抽象方法

- RecursionError # 超出最大递归深度

- SyntaxError # 语法错误

- IndentationError # 缩进错误

- TabError # tab错误

- SystemError # 解释器中断

- TypeError # 类型错误

- ValueError # 赋值错误

- UnicodeError #

- UnicodeEncodeError # unicode编码错误

- UnicodeDecodeError # unicode解码错误

- UnicodeTranslateError # unicode转换错误

- Warning #

- DeprecationWarning # 操作不赞成警告

- PendingDeprecationWarning # 表明此操作将来会被弃用

- UserWarning # 用于用户生成警告

- SyntaxWarning # 语法可疑警告

- RuntimeWarning # 运行警告

- FutureWarning # 将会改变警告

- ImportWarning # 导入警告

- UnicodeWarning # unicode相关警告

- BytesWarning # 字节相关警告

- ResourceWarning # 资源使用情况警告

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190125G15WG500?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券