为什么可以使用 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
) 的别名。是的,文档以另一种方式指出了别名,以方便最终用户使用。
从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
) 的别名。是的,文档以另一种方式指出了别名,以方便最终用户使用。