从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
装饰器。
答案 0 :(得分:7)
您没有使用open
函数作为上下文管理器。它是open(...)
调用表达式的结果,它是上下文管理器。 open()
返回一个文件对象,该对象具有__enter__
和__exit__
方法;请参阅io.IOBase
documentation:
IOBase 也是一个上下文管理器,因此支持with语句。
您可以阅读with
语句,如下所示:
_context_manager = open('what_are_context_managers.txt', 'r')
with _context_manager as infile:
请注意,_context_manager.__enter__()
的返回值最终会在此处分配给infile
。对于文件对象,file.__enter__()
返回self
,因此您可以通过该方式访问同一个对象。
作为旁注;你得到了错误的open()
函数。 open()
内置的实际定义是io.open()
的别名,请参阅_iomodule.c
source code。别名在initstdio()
in pylifecycle.c
中设置(其中io.OpenWrapper
为itself an alias for _io.open
)。是的,文档说明了别名为最终用户提供了另一种方式。