Python深入-14-with上下文

一、 上下文管理器和 with 块

上下文管理器对象存在的目的是管理 with 语句,就像迭代器的存在是为了管理 for 语句一样。with 语句的目的是简化一些常用的 try/finally结构。这种结构可以保证一段代码运行完毕后执行某项 操作,即便那段代码由于 return 语句、异常或 sys.exit() 调用而终止,也执行指定的操作。finally子句中的代码通常用于释放重要的资源,或者还原临时改变的状态。 
    上下文管理器接口包含 __enter____exit__ 两个方法。with 语句开始运行时,Python 在上下文管 理器对象上调用 __enter__ 方法。with 块运行结束,或者由于什么原因终止后,Python 在上下文管理器 对象上调用 __exit__ 方法。 
** 把文件对象当成上下文管理器使用 **

# fp 绑定打开的文件,因为文件的 __enter__ 方法返回 self。
with open('demo10.py'as fp:
    # 从 fp 中读取 60 个 Unicode 字符
    src = fp.read(60)

print(fp)  # <_io.TextIOWrapper name='demo10.py' mode='r' encoding='cp936'>
# ❺ 但是不能使用 fp 继续读取文本,因为在 with 块的末尾,Python 调用 TextIOWrapper.__exit__ 方
# 法把文件关闭了。
print(fp.read(60)) # 这个会报错

碰巧,open() 函数返回一个 TextIOWrapper 实例,而该实例的 __enter__ 方法返回 self。不过,其 他类的 __enter__ 方法可能会返回其他对象,而不返回上下文管理器实例。不管控制流以哪种方式退出 with 块,都在上下文管理器对象上调用 __exit__ 方法,而不是在 __enter_ 方法返回的对象上调用。with 语句的 as 子句是可选的。对 open 函数来说,必须加上 as 子句,以便获取文件的引用,在引用上 调用方法。不过,有些上下文管理器返回 None,因为没什么有用的对象能提供给用户。

二、 if 语句之外的 else 块

else 子句不仅能在 if 语句中使用,还能在 for、while 和 try 语句中使用。 
else 子句的规则如下。

  • for 仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 块。

  • while 仅当 while 循环因条件为假值而退出时(即 while 循环没有被 break 语句中止)才运行 else 块。

  • try 仅当 try 块没有抛出异常时才运行 else 块。官方文档还指出:“else 子句抛出的异常不由前面的 except 子句处理。”

在所有情况下,如果异常或者 return、break 或 continue 语句导致控制权跳到了复合语句的主块之 外,则 else 子句也被跳过。

for item in my_list:
    if item.flavor == 'banana':
        break
else:
    raise ValueError('No banana flavor found!')
try:
    dangerous_call()
    after_call()
except OSError:
    log('OSError...')


原文始发于微信公众号(Python之家):Python深入-14-with上下文

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/198365.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!