《Fluent Python》笔记 else子句和上下文管理器
else子句
else 子句不仅能在 if 语句中使用, 还能在 for、 while 和 try 语句中使用。在if语句中,else子句的作用是,如果不满足if的条件,那么执行else子句中的代码,这是Python学习中的基础知识。
在 for 语句后加 else 子句作用是,仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 子句中的代码。
1 |
|
在 while 语句后加 else 子句作用是,仅当 while 循环因为条件为假值而退出时(即 while 循环没有被 break 语句中止) 才运行 else 子句中的代码。
1 |
|
在 try 语句后加 else 子句作用是, 仅当 try 代码块中没有异常抛出时才运行 else 子句中的代码。
1 |
|
在上述三种情况下, 如果异常或者 return
、 break
或 continue
语句导致控制权跳到了复合语句的主块之外,那么 else 子句也会被跳过。
上下文管理器和with块
上下文管理器协议包含 __enter__
和 __exit__
两个方法。 with
语句开始运行时, 会在上下文管理器对象上调用 __enter__
方法。 with
语句运行结束后, 会在上下文管理器对象上调用 __exit__
方法。
我在写代码时,总会在操作文件时使用with
语句。通过with...as...
语句把文件对象作为上下文管理器使用。
1 |
|
执行 with
后面的表达式得到的结果就是上下文管理器对象。因为open
函数返回 TextIOWrapper
类的实例,所以此时把TextIOWrapper
对象作为上下文管理器对象,with
语句运行是,调用TextIOWrapper
对象的 __enter__
方法,返回 self
赋值给as
后的f
,所以 f
仍然是TextIOWrapper
对象,即可以正常进行文件读写等操作。当with
语句块结束时,调用上下文管理器也就是TextIOWrapper
对象(这里的TextIOWrapper
对象不是 __enter__
方法返回 self
)的 __exit__
方法,即自动完成了文件关闭的操作。
自定义上下文管理器类示例:
1 |
|
__enter__
方法的参数只有隐式的self
一个,不会传入任何参数。
__exit__
方法的参数如下:
exc_type
异常类(例如 ZeroDivisionError)。
exc_value
异常实例。 有时会有参数传给异常构造方法, 例如错误消息, 这些参数可以使用
exc_value.args
获取。traceback
traceback
对象。
@contextmanager
@contextmanager
是contextlib
模块中的装饰器。其作用是减少创建上下文管理器的样板代码量。使用它就可以不用像上面那样创建一个类仍然会分别定义 __enter__
和 __exit__
方法,只需实现有一个 yield
语句的生成器函数即可。
在使用 @contextmanager
装饰的生成器函数中,yield
语句前面的所有代码在 with
块开始时(即解释器调用 __enter__
方法时) 执行, yield
语句后面的代码在 with
块结束时(即调用 __exit__
方法时) 执行。contextlib.contextmanager
装饰器会把生成器函数包装成实现了 __enter__
和 __exit__
方法的类。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!