网站的哪些标签需要优化,泰安市景区建设网站,医院门户网站模板,深圳网络推广公司怎么样文章目录1. else2. with上下文管理器3. contextlib模块实用工具4. contextmanager 装饰器learn from 《流畅的python》
1. else
for/else、while/else 和 try/else 前两者 只有在 没有被break 时#xff0c;才会运行 else try 块中没有异常抛出时 才运行 else
for i in ran…
文章目录1. else2. with上下文管理器3. contextlib模块实用工具4. contextmanager 装饰器learn from 《流畅的python》
1. else
for/else、while/else 和 try/else 前两者 只有在 没有被break 时才会运行 else try 块中没有异常抛出时 才运行 else
for i in range(3):print(i)
else:print(finish, no break)# finish, no breakfor i in range(3):if i 2:breakprint(i)
else:print(break)# 无输出i 0
while i 3:print(i)i 1
else:print(no break) # no breaki 0
while i 3:if i2:breakprint(i)i 1
else:print(break) # 无输出arr [0]
try:arr[0] 1
except:print(error) # 无输出
else:print(no error, run else)# no error, run elsearr []
try:arr[0] 0
except:print(error) # error
else:print(error, will not run else) # 无输出
finally:print(finish) # finish
# finally 子句中的代 码通常用于释放重要的资源或者还原临时变更的状态else 这么用的比较少
2. with上下文管理器
上下文管理器协议包含 __enter__ 和 __exit__ 两个方法
with 语句 运行时会在上下文管理器对象上调用 __enter__ 方法with 语句 结束后会在上下文管理器对象上调用 __exit__ 方法以此扮 演 finally 子句的角色释放重要的资源或者 还原临时变更的状态如 关闭文件等
class LookingGlass:def __enter__(self): # 没有其它的参数了import sysself.original_write sys.stdout.writesys.stdout.write self.reverse_writereturn ABCDdef reverse_write(self, text): # 反转字符串实现输出self.original_write(text[::-1])def __exit__(self, exc_type, exc_value, traceback):# exc_type 异常类# exc_value 异常实例# traceback 对象# 在 try/finally 语句的 finally 块中调用 sys.exc_info()# 得到的就是 __exit__ 接收的这三个参数import syssys.stdout.write self.original_writeif exc_type is ZeroDivisionError:print(Please DO NOT divide by zero!)return Truewith LookingGlass() as what:# 进入 __enter__ 函数时返回的 ABCD 字符串存入 whatprint(Michael learning python)# nohtyp gninrael leahciMprint(what)# DCBA
print(Michael learning python)
# Michael learning python
print(what)
# ABCDmanager LookingGlass()
print(manager)
# __main__.LookingGlass object at 0x00000231226F2190
string manager.__enter__()
print(string) # DCBA
print(string ABCD) # eurT, 所有的输出经过管理器的 反向输出处理了
print(string DCBA) # eslaF, 所有的输出经过管理器的 反向输出处理了
print(manager)
# 0912F62213200000x0 ta tcejbo ssalGgnikooL.__niam__
manager.__exit__(None, None, None) # 还原了正常的输出
print(string) # ABCD3. contextlib模块实用工具
closing 如果对象 提供了 close() 方法但没有实现 __enter__/__exit__ 协议那么可以使用这个函数构建上下文管理器suppress, 构建临时 忽略指定异常 的上下文管理器contextmanager装饰器 把简单的 生成器函数 变成 上下文管理器这样就不用创建类去实现管理器协议了ContextDecorator这是个基类用于定义基于类的上下文管理器。这种上下文管理器 也能用于 装饰函数在受管理的上下文中运行整个函数ExitStack这个上下文管理器 能进入多个 上下文管理器。with 块结束时ExitStack 按照后进先出的顺序调用栈中各个上下文管理器的 __exit__ 方法。 如果事先不知道 with 块要进入 多少个上下文管理 器可以使用这个类。例如同时打开任意一个文件列表中的所有文件
使用最广泛的是 contextmanager 装饰 器因此要格外留心。 这个装饰器也有迷惑人的一面因为它与迭代 无关却要 使用 yield 语句
4. contextmanager 装饰器
contextmanager 装饰器能减少代码量因为 不用编写一个完整的类定义 __enter__ 和 __exit__ 方法而 只需实现 有一个 yield 语句的生成器生成想让 __enter__ 方法返回的值在使用 contextmanager 装饰的生成器中yield 语句的作用是 把函数的定义体分成两部分 yield 语句前面的所有代码在 with 块开始时 即解释器调用 __enter__ 方法时执行 yield 语句后面的代码在 with 块结束时即调用 __exit__ 方法时执行
import contextlibcontextlib.contextmanager
def looking_glass1():import sysoriginal_write sys.stdout.writedef reverse_write(text):original_write(text[::-1])sys.stdout.write reverse_writeyield ABCD # 产出的值绑定到 as 目标上# 执行 with 块代码时函数会在这里暂停sys.stdout.write original_write# 控制权一旦跳出 with 块继续执行 yield 语句之后的代码with looking_glass1() as what:print(Michael learning python)print(what)
# nohtyp gninrael leahciM
# DCBA
print(Michael learning python)
print(what)
# Michael learning python
# ABCD其实contextlib.contextmanager 装饰器会把函数包装成实现 __enter__ 和 __exit__ 方法的类
用于原地重写文件的上下文管理器
import csv
with inplace(csvfilename, r, newline) as (infh, outfh): reader csv.reader(infh) writer csv.writer(outfh) for row in reader: row [new, columns] writer.writerow(row)inplace 函数是个上下文管理器为同一个文件提供了两个句柄例中的 infh 和 outfh以便同时读写同一个文件。比标准库中的 fileinput.input 函数 易用