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

时间:2017-05-03 10:12:52

标签: python contextmanager

从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装饰器。

1 个答案:

答案 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.OpenWrapperitself an alias for _io.open)。是的,文档说明了别名为最终用户提供了另一种方式。