Detailed explanation of the context manager of python

Context manager

Definition : Refers to the object
function that implements the context management protocol method : mainly used to release resources (such as open files, network connections, database connections, locks on objects, etc.)

Two methods of the context management protocol:
**1__enter__(self)** creates and returns a resource object that can be referenced for use by the program in the with statement block
**2__exit__(self, type, value, tb)** Exit the context Called when, mainly used to safely release resources

The form of the with statement using the context manager is:

with context as val:
      pass

val will obtain the resource reference returned by the __enter__() method in the context manager for use in the code block behind with

The return value of the open function

with open("filename", encoding="utf-8") as fp:
      fp.read()

The function open() in this piece of code returns an object that implements the context management protocol method, not a resource ( file handle) as we think , which requires the __enter__ (self) method of the context manager to return the file handle , For reference to the variable fp after as.
We can use python built-in functions to check the attributes of the object returned by open():
namely:
Insert picture description here
Insert picture description here
open()–>context manager– > enter (self)–>resources

函数open
上下文管理器
__enter__
资源

We can also implement our own context manager. The
code is as follows:

class MyFileMgr:
   def __init__(self, fp=None, filename):
      self.fp = fp
      self.filename = filename
      
   def __enter__(self):  # 主要用于返回一个可以引用的资源
      self.fp = open(self.filename, encoding="utf-8")
      return self.fp
   def __exit__(self, t, v, tb):  # 用于释放资源
      if self.fp:
         fp.close()

if __name__ == '__main__':
    with MyFileMgr as fp:
         fp.read()

The module related to the context manager in the Py standard library: Contextlib:
It provides a decorator that converts the generator into a context manager: contextmanager

import contextlib
@contextlib.contextmanager
def my_mgr(s, e):
    print(s)
    yield s + ' ' + e
    print(e)


if __name__ == "__main__":
    with my_mgr('start', 'end') as val:
        print(val)

Running effect: start
start end
end

Code debugging:
Insert picture description here

In this example:
because the generator is converted into a context manager, the statement below yield will also release resources due to __exit__() in the context manager, execute next(), and execute the output end

Guess you like

Origin blog.csdn.net/weixin_43495262/article/details/106535318