许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  《Fluent Python》笔记:else子句与上下文管理器

《Fluent Python》笔记:else子句与上下文管理器

阅读数 2
点赞 0
article_banner

else子句

else 子句不仅能在 if 语句中使用, 还能在 for、 while 和 try 语句中使用。在if语句中,else子句的作用是,如果不满足if的条件,那么执行else子句中的代码,这是Python学习中的基础知识。

在 for 语句后加 else 子句作用是,仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 子句中的代码。

for i in items:
	i -= 1
else:
	# do something

在 while 语句后加 else 子句作用是,仅当 while 循环因为条件为假值而退出时(即 while 循环没有被 break 语句中止) 才运行 else 子句中的代码。

while i < 3:
	i -= 1
else:
	# do something

在 try 语句后加 else 子句作用是, 仅当 try 代码块中没有异常抛出时才运行 else 子句中的代码。

try:
	i = 1
else:
	# do something

在上述三种情况下, 如果异常或者 returnbreakcontinue 语句导致控制权跳到了复合语句的主块之外,那么 else 子句也会被跳过。

上下文管理器和with块

上下文管理器 协议  包含 __enter____exit__ 两个方法。 with 语句开始运行时, 会在上下文管理器对象上调用 __enter__ 方法。 with 语句运行结束后, 会在上下文管理器对象上调用 __exit__ 方法。

我在写代码时,总会在操作文件时使用with语句。通过with...as...语句把文件对象作为上下文管理器使用。

with open("file.txt") as f: # f绑定到打开的文件上, 因为文件的 __enter__ 方法返回 self
	txt = f.readline()
print(txt)

执行 with 后面的 表达式  得到的结果就是上下文管理器对象。因为open函数返回 TextIOWrapper 类的实例,所以此时把TextIOWrapper对象作为上下文管理器对象,with语句运行是,调用TextIOWrapper对象的 __enter__ 方法,返回 self 赋值 as后的f,所以 f 仍然是TextIOWrapper对象,即可以正常进行文件读写等操作。当with语句块结束时,调用上下文管理器也就是TextIOWrapper对象(这里的TextIOWrapper对象不是 __enter__ 方法返回 self)的 __exit__ 方法,即自动完成了文件关闭的操作。

自定义上下文管理器类示例:

class LookingGlass:
    
	def __enter__(self):
        import sys
        self.original_write = sys.stdout.write
        sys.stdout.write = self.reverse_write
        return 'JABBERWOCKY'

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

    def __exit__(self, exc_type, exc_value, traceback):
        import sys
        sys.stdout.write = self.original_write
        if exc_type is ZeroDivisionError:
        	print('Please DO NOT divide by zero!')
        	return True
        
if __name__ == "__main__":
	with LookingGlass() as what:
		print('Alice, Kitty and Snowdrop')
		print(what)

__enter__方法的参数只有隐式的self一个,不会传入任何参数。

__exit__方法的参数如下:

  • exc_type 异常类(例如 ZeroDivisionError)。
  • exc_value 异常实例。 有时会有参数传给异常构造方法, 例如错误消息, 这些参数可以使用 exc_value.args 获取。
  • traceback traceback 对象。

@contextmanager

@contextmanagercontextlib模块中的装饰器。其作用是减少创建上下文管理器的样板代码量。使用它就可以不用像上面那样创建一个类仍然会分别定义 __enter____exit__ 方法,只需实现有一个 yield 语句的生成器函数即可。

在使用 @contextmanager 装饰的生成器函数中,yield语句前面的所有代码在 with 块开始时(即 解释器  调用 __enter__ 方法时) 执行, yield语句后面的代码在 with 块结束时(即调用 __exit__ 方法时) 执行。contextlib.contextmanager 装饰器会把生成器函数包装成实现了 __enter____exit__ 方法的类。

import contextlib

@contextlib.contextmanager
def looking_glass():
    import sys
    original_write = sys.stdout.write
    
    def reverse_write(text):
    	original_write(text[::-1])	# 闭包的知识,访问自由变量original_write
   
    sys.stdout.write = reverse_write
    yield 'JABBERWOCKY'
    sys.stdout.write = original_write
    
if __name__ == "__main__":
	with LookingGlass() as what:
		print('Alice, Kitty and Snowdrop')
		print(what)



免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删


相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空