Why can you use open() as context manager?

☆樱花仙子☆ 提交于 2021-02-07 10:54:43

问题


From Python's source code of open, I think open is just a normal function.

Why can we use it like below?

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

Since is neither implements __enter__ nor __exit__, nor uses contextlib.contextmanager decorator.


回答1:


You are not using the open function as a context manager. It is the result of the open(...) call expression that is the context manager. open() returns a file object, and it is that object that has __enter__ and __exit__ methods; see the io.IOBase documentation:

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

You can read the with statement like this:

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

Note that it is the return value of _context_manager.__enter__() that ends up being assigned to infile here. For file objects, file.__enter__() returns self, so you can get access to the same object that way.


As a side-note; you got the wrong open() function. The actual definition of the open() built-in is an alias for 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). And yes, the documentation states the alias points the other way for end-user ease.



来源:https://stackoverflow.com/questions/43757161/why-can-you-use-open-as-context-manager

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!