为什么你可以使用open()作为上下文管理器?

scr*_*boy 0 python contextmanager

从Python的源代码来看open,我认为open这只是一个普通的函数.

为什么我们可以像下面这样使用它?

with open('what_are_context_managers.txt', 'r') as infile:
    for line in infile:
        print('> {}'.format(line))
Run Code Online (Sandbox Code Playgroud)

因为既不是实现__enter__也不是__exit__,也不使用contextlib.contextmanager装饰器.

Mar*_*ers 7

您没有将该open函数用作上下文管理器.它是调用表达式结果,open(...)它是上下文管理器.open()返回一个文件对象,该对象具有__enter____exit__方法; 看io.IOBase文档:

IOBase也是一个上下文管理器,因此支持with语句.

您可以阅读如下with语句:

_context_manager = open('what_are_context_managers.txt', 'r')
with _context_manager as infile:
Run Code Online (Sandbox Code Playgroud)

请注意,它的返回值_context_manager.__enter__()最终被分配到infile此处.对于文件对象,file.__enter__()返回self,这样您就可以以这种方式访问​​同一个对象.


作为旁注; 你的open()功能错了.open()内置的实际定义是别名io.open(),请参阅_iomodule.c源代码.的别名设置在initstdio()pylifecycle.c(其中io.OpenWrapper本身的别名_io.open).是的,文档说明别名指向最终用户容易的另一种方式.