013-with open() as the usage and with context manager (Context manager)

The usage of with open() as and the with context manager (Context manager)


1. Basic reading and writing:

Read the file:

1. Open the file in the way of reading

f = open(“1.txt”, “r”)

2. Read the content of the file

str = f.read()

print(str)

3. Close the file

f.close()

Write file:

1. Open the file as written

f = open(“2.txt”, “w”)

2. Write the content of the file

str = f.write(“Welcome to 北京!”)

3. Close the file

f.close()


2. Demonstration of error code:

What is the problem with this method?

1. Open the file in the way of reading

f = open(“1.txt”, “r”)

2. Read the content of the file

f.write(“xxxxx”)

f.close()

Since IOError may be generated during file reading and writing, once an error occurs, the following f.close() will not be called.

Three, optimize the code:

1) In order to ensure that the file can be closed correctly regardless of whether there is an error, we can use try… finally to achieve:

try:

1. Open the file in the way of reading

f = open(“1.txt”, “r”)

2. Read the content of the file

f.write(“xxxxx”)

except IOError as e:

print("File operation error", e)

finally:

f.close()

2) Python introduced the with statement to automatically help us call the close() method:

try:

1. Open the file in the way of reading

with open(“1.txt”, “r”) as f:

2. Read the content of the file

f.write(“xxxxx”)

except IOError as e:

print("File operation error", e)

》This is the same as the previous try...finally, but the code is more concise, and there is no need to call the f.close() method.

》Use the with keyword. The return value of the open method is assigned to the variable f. When leaving the with code block, the system can automatically call the f.close() method


Four, the principle of with context manager

Before the principle of with, another concept is involved, which is the context manager (Context Manager).

1) The context can be understood as the (language) environment. (Although the context is called the context, but the program generally only has the context, but it is called the context.

2) The essence of the context manager is to support the with operation. Any __enter__() 和 __exit__()object that implements the method can be called a context manager, and context manager objects can use the with keyword. Obviously, the file object also implements the context manager protocol.

1. Code demonstration:
"""
类:  MyFile()
类方法:
   1. __enter__()  上文方法
   2. __exit__()   下文方法
   3. __init__()   方法,接收参数并且初始化

目的:验证上下⽂管理器(Context Manager)
   with MyFile('hello.txt', 'r') as file:
       file.read()
   
"""

class MyFile(object):

   # 1. __enter__()  上文方法
   def __enter__(self):
       print("进入上文....")
       # 1,打开文件 
       self.file = open(self.file_name, self.file_model)
       # 2,返回打开的文件资源
       return self.file

   # 2. __exit__()   下文方法
   def __exit__(self, exc_type, exc_val, exc_tb):
       print("进入下文....")
       # 关闭文件资源
       self.file.close()

   # 3. __init__()   方法,接收参数并且初始化
   def __init__(self, file_name, file_model):
       # 局部变量定义成实例属性 -> 在类里面调用
       # 保存文件名和文件打开模式 -> 到实例属性中
       self.file_name = file_name
       self.file_model = file_model


if __name__ == '__main__':

   with MyFile("hello.txt", "r") as file:
       # 开始读取文件
       file_data = file.read()
       print(file_data)
       

Results of the:

进入上文....
hello,python!
进入下文.... 

__enter__()The method returns the resource object, which is the file object you are about to open, and you can __exit__()do some cleanup operations.

Because the File class implements the context manager, you can use the with statement.

2. Another way to realize the context manager

Python provides a decorator for the contextmanager module @contextmanager, which further simplifies the implementation of context manager. The function is divided into two parts by yield, the statement before yield __enter__ ()is executed in the method, and the statement after yield __exit__()is executed in the method. The value immediately after yield is the return value of the function.

Decorator: Do not modify the code of the original function (function to be modified), add new functions (methods)

"""
思路:
    def myopen(file_name,file_model)

            上文(打开资源)
            yield
            下文(关闭资源)

装饰器装饰函数的步骤:
1. 导入模块 from contextlib import contextmanager
2. 开始装饰 @contextmanager


"""
from contextlib import contextmanager


@contextmanager
def myopen(file_name,file_model):

    print("进入上文")
    # 1.打开文件
    file = open(file_name,file_model)
    # 2.返回资源
    yield file
    print("进入下文")
    # 下文
    # 3. 关闭资源
    file.close()


with myopen("hello.txt", "r") as file:
    file_data = file.read()
    print(file_data)
     

Results of the:

进入上文....
hello,python!
进入下文.... 

V. Summary

1) Python provides the with syntax to simplify the subsequent cleanup operations of resource operations, and the implementation principle is built on top of the context manager protocol ( __enter__and __exit__)

2) If an exception occurs during the opening process in the with code, you need to use try-except to capture

3) Python also provides a contextmanager decorator to further simplify the implementation of upper and lower managers.


Six, application with open() as

1. Create a write file
request_data = urllib.request.urlopen(img_url)

#在(指定路径下 )--> 创建文件 --> 准备保存
 
with open('/home/cfl/Desktop/+ file_name, "wb") as file:

#在(当前目录) --> 创建文件 --> 准备保存

with open(file_name, "wb") as file:
          while True:
                file_data = request_data.read(1024)
                if file_data:
                    file.write(file_data)
                else:
                    break
2. Open the file for reading

recv_data = new_client_socket.recv(1024)
file_name = recv_data.decode() #Read the
file content according to the file name
try:
with open(file_name, "rb") as file:
Send the read file content to the client (loop)
while True:
file_data = file.read(1024)
judge whether the end of the file has been read
if file_data:
send file
new_client_socket.send(file_data)
else:
break
except Exception as e:
print("File %s download failed"% file_name)
else:
print("File %s downloaded successfully"% file_name

Guess you like

Origin blog.csdn.net/mmmmmCJP/article/details/109596451