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

Why can you use open() as context manager?

从Python的source code of open来看,我认为open只是一个普通的函数。

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

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

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

您没有将 open 函数用作上下文管理器。 open(...) 调用表达式 的 结果是上下文管理器。 open() return 是一个文件对象,正是该对象具有 __enter____exit__ 方法;请参阅 io.IOBase documentation:

IOBase is also a context manager and therefore supports the with statement.

您可以这样阅读 with 语句:

_context_manager = open('what_are_context_managers.txt', 'r')
with _context_manager as infile:

请注意,_context_manager.__enter__() 的 return 值最终分配给了此处的 infile。对于文件对象,file.__enter__() returns self,因此您可以通过这种方式访问​​同一对象。


作为旁注;你得到了错误的 open() 函数。 open() 内置函数的实际定义是 io.open(), see the _iomodule.c source code. The alias is set in initstdio() in pylifecycle.c (where io.OpenWrapper is itself an alias for _io.open) 的别名。是的,文档以另一种方式指出了别名,以方便最终用户使用。