首页 > 编程语言 >【Python】笔记:上下文管理器和else快

【Python】笔记:上下文管理器和else快

时间:2022-12-03 21:34:58浏览次数:52  
标签:__ sys 管理器 Python else write print

上下文管理器和else快

类似于 then 的 else

for...else... 仅在 for 循环运行完毕后运行 else, 不能被 break

while...else... 仅在 while 条件为 false 而退出后运行 else, 不能被 break

try...else... 仅在 try 没有抛出异常后, 运行 else

注: 若存在 break, continue, return 把控制权跳到了复合语句的主块外, else 也会被跳过

for item in ('A', 'B', 'C'):
    if item == 'D':
        break
else:
    raise ValueError('No D')
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

Cell In [4], line 5
      3         break
      4 else:
----> 5     raise ValueError('No D')


ValueError: No D
try:
    print("RUA")
except OSError:
    print("WARMING")
else:
    print("after rua")
RUA
after rua

上下文管理器和with块

with 化简 try...finally... 模式

上下文管理器协议包含 __enter____exit__

with 后跟 上下文管理器对象

as xxx 可选

__exit__ 中返回 True 以外的值, with 中的任何异常会向上冒泡, 默认返回 None, 即会向上冒泡异常

with open(r'C:\Users\qiany\OneDrive\Document\Code\python\study\FluentPython\data\rua.txt') as fp:
    src = fp.read(60)
    print(src)

print(fp.encoding)  # fp 依旧可以使用(仅限读取属性)
print(fp.read(60))  # 不能在 fp 上执行 I/O 操作, 因为 with 末尾调用 __exit__将文件关闭了
ruaruaruaruaruaruaruaruaruaruaruaruaruaruaruaruaruaruaruarua
cp936



---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

Cell In [12], line 6
      3     print(src)
      5 print(fp.encoding)  # fp 依旧可以使用(仅限读取属性)
----> 6 print(fp.read(60))  # 不能在 fp 上执行 I/O 操作, 因为 with 末尾调用 __exit__将文件关闭了


ValueError: I/O operation on closed file.
class LookingGlass:
    def __enter__(self):  # Python 调用 enter 不会传入任何参数
        import sys
        self.original_write = sys.stdout.write
        sys.stdout.write = self.reverse_write  # 猴子补丁
        return 'RUAAAAA'

    def reverse_write(self, text):
        self.original_write(text[::-1])

    def __exit__(self, exc_type, exc_value, traceback):
        import sys  # python 会缓存导入的模块, 重复导入 sys 不会浪费资源
        sys.stdout.write = self.original_write
        if exc_type == ZeroDivisionError:
            print('Dont divide zero')
            return True  # __exit__中返回True以外的值, with中的任何异常会向上冒泡

print('--- 使用 with 方法 ---')
with LookingGlass() as what:
    print("QAQ233")
    print(what)

print("what", what)

print('--- 不使用 with 方法 ---')
manager = LookingGlass()
monster = manager.__enter__()
print(monster)
manager.__exit__(None, None, None)

--- 使用 with 方法 ---
332QAQ
AAAAAUR
what RUAAAAA
--- 不使用 with 方法 ---
AAAAAUR

exc_type 异常类 eg.ZeroDivisionError

exc_value 异常实例 exc_value.args 可捕获 Error(value)value

traceback traceback对象

contextlib 模块中的实用工具

方法 释义
closing 如果对象提供了 close() 方法, 但没有实现 __enter__/__exit__ 协议, 那么可通过这个函数构造上下文
suppress 构建临时忽略指定异常的上下文管理器
@contextmanager 生成器函数 变成 上下文管理器
ContextDecorator 基类, 用于定义 基于类 的上下文管理器
ExitStack 这个 上下文管理器 能进入 多个 上下文管理器。with 结束时, ExitStack后进先出 的顺序调用栈中各个上下文管理器的 __exit__。eg.同时打开多个文件

使用 @contextmanager

在使用 @contextmanager 装饰的生成器中, yield语句的作用是把函数的定义体分成两部分,

  • yield的代码在 with 块开始时(解释器调用 __enter__方法时) 执行

  • yield的代码在 with 块结束时(解释器调用 __exit__方法时) 执行

  • yield 的值绑定到 as 的目标变量上去

注意: yield 语句最好放在 try...finally... 或在 with 语句中, 因为我们永远不知道用户会在 with 中干什么

import contextlib

@contextlib.contextmanager
def looking_glass():
    import sys
    original_write = sys.stdout.write

    def reverse_write(text):
        original_write(text[::-1])

    sys.stdout.write = reverse_write
    yield 'RUAAAAAA'
    sys.stdout.write = original_write

with looking_glass() as what:
    print("QAQ233")
    print(what)
332QAQ
AAAAAAUR
# 加入异常处理
import contextlib

@contextlib.contextmanager
def looking_glass():
    import sys
    original_write = sys.stdout.write

    def reverse_write(text):
        original_write(text[::-1])

    sys.stdout.write = reverse_write
    msg = ''
    try:
        yield 'RUAAAAAA'
    except ZeroDivisionError:
        msg = 'Dont divie by zero'
    finally:
        sys.stdout.write = original_write
        if msg:
            print(msg)

with looking_glass() as what:
    print("QAQ233")
    print(what)

标签:__,sys,管理器,Python,else,write,print
From: https://www.cnblogs.com/Zinc233/p/FluentPython_S15.html

相关文章

  • 【Python】笔记:可迭代的对象、迭代器和生成器
    可迭代的对象、迭代器和生成器importreimportreprlibRE_WORD=re.compile('\w+')classSentence_v1:def__init__(self,text):self.text=text......
  • 【Python】笔记:接口:从协议到抽象基类
    S11接口:从协议到抽象基类#random.shuffle就地打乱fromrandomimportshufflel=list(range(10))shuffle(l)print(l)shuffle(l)print(l)[0,6,3,2,4,8,......
  • 【Python】笔记:正确重载运算符
    正确重载运算符一元运算符-(__neg__)+(__pos__)最好返回self的副本~(__invert__)对整数位按位取反(~x==-(x+1))print(~2)-3中辍运算符+fromarray......
  • 回文链表-python
    问题:给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。思考:对称结构要想到stack方案一:双指针法将节点值赋值到数组......
  • Python内容写入文件
       Python允许你将内容写入文件,方式与使用print()函数将字符串‘写’到屏幕上类似,但是,如果打开文件时用读模式,就不能写入,你需要以纯文本模式或添加纯文本模式打开该文......
  • Python 跳动的小球
    一、实验内容:跳动的小球游戏介绍二、实验对象:《零基础学Python》第13章Pygame游戏编程实例01用以下代码创建一个游戏弹窗:导入pygame模块并且用init()方法初始化,设置窗......
  • n202_python数据类型和数据结构
    3.数据类型和数据结构python的数据类型大致可以分为两种:python自带的内置数据类型和第三方扩展包中的数据类型。其中,python自带的内置数据类型可以分为两种:可变数据类......
  • Python爬取中国最好大学排行榜报错TypeError: unsupported format string passed to N
    ​本文使用的是如下网址:http://gaokao.xdf.cn/201911/10991728.html1问题分析与解决报错为类型错误,显示我们传递了不支持的格式字符串1.1strip()我们查看网页源码,......
  • python常用第三方库
    python常用第三方库官网主页查询、下载和发布Python包或库官网地址参考来源网络爬虫requests:https://pypi.org/project/requests/简洁且简单的处理HTTP请求的......
  • [oeasy]python0024_ 输出时间_time_模块_module_函数_function
    输出时间回忆上次内容​print​​函数有个默认的​​end参数​​​end参数​​的值可以是任意字符串​​end参数​​的值会输出到结尾位置​​end参数​​的默认值是......