Operation can file object:
with open('a.txt') as f:
'代码块'
Above it is called context management protocol, namely with the statement.
Imagine you have two nodes related operations need to be performed, then, but also a piece of code placed in the middle of them. Such as opening a file, the file operation, and then close the file.
File opening and closing operation of a pair of the document is.
Common use case context manager: Yes Lock and unlock resources, opening and closing files.
Context Manager
Context Manager Protocol: means need to achieve __ __ Enter and Exit __ __ method.
Iterator has just iterator protocol, like the iterator protocol __ iter __ and __ next __ methods need to achieve.
Context manager, which is supported by the object context management protocol, a simple point of speaking that is, a class that implements two methods __ enter __ and __ exit __. This class is also called, the context manager class.
Open write a class that is a context manager:
class Open:
def __init__(self, filepath, encoding):
self.filepath = filepath
self.encoding = encoding
def __enter__(self): # 当这个类被with关键字执行时,就自动调用这个方法。有返回值则调用给 as 声明的变量
print('当这个类被with关键字执行时,就自动调用这个方法。有返回值则调用给 as 声明的变量')
def __exit__(self, exc_type, exc_val, exc_tb):
print('with 中代码块执行完就执行我这个函数')
with Open('1.txt', 'UTF-8') as f:
print('with 里面的代码块')
'''
结果:
当这个类被with关键字执行时,就自动调用这个方法。有返回值则调用给 as 声明的变量
with 里面的代码块
with 中代码块执行完就执行我这个函数
'''
__ exit __(self, exc_type, exc_val, exc_tb):
Representing three parameters which are: the exception type, exception value, traceability information.
Note: After an exception with the statement block of code appears, with the code can not be executed
Based class: full implementation of the Open method
A context manager class, at least to define __ __ Enter and Exit __ __ method.
class Open:
def __init__(self, filepath, method):
self.file = open(filepath, method, encoding='utf-8')
def __enter__(self):
return self.file
def __exit__(self, type, value, traceback):
self.file.close()
with Open('1.txt', 'w') as f:
f.write('1111111111')
Let's look at the bottom of what happened?
- with the staging of the first sentence of exit __ __ Open class method
- Then call __ enter __ method Open class
- __ enter __ method to open the file and return to the with statement
- Open file handle to the back as the parameter f
- Performing with the inside of the block.
- The staging method before calling __ exit __
- Close the file
Between Step 4 and step 6, if an exception occurs, Python will abnormal type, transfer value, traceback to Exit __ __ method.
When an exception occurs, with statement what steps to take?
- with the exception pass type, value, traceback method to __ exit __
- with exception handling let __ exit __
- If __ exit __ returns True, then the exception is elegantly handled.
- If __ exit __ returned is anything other than True, that this exception will be thrown out with the statement.
When __ exit __ () return value is True, then the exception will be emptied, as if got nothing happened, after the sentence with normal execution ..
Complete simulation Open:
class Open:
def __init__(self, filepath, mode='r', encoding='utf-8'):
self.filepath = filepath
self.mode = mode
self.encoding = encoding
def __enter__(self):
self.file = open(self.filepath, mode=self.mode, encoding=self.encoding)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type)
self.file.close()
return True
with Open('1.txt', 'w', encoding='utf-8') as f:
f.write('哈哈哈')
f.werwer # 抛出异常,交给exit处理。后面的代码正常运行
advantage
- Use with the statement of purpose is to put the code block with the execution after the end with, clean up automatically, without intervention.
- The need to manage some resources such as files, network connections, and lock the programming environment, you can customize the mechanism automatically release resources __ exit __ in.
Generating a context manager implemented on
contextlib module: a generator can be implemented using a context manager, instead of using a class. As we all know, in the class also need to implement __ enter __ and __ exit __.
from contextlib import contextmanager
@contextmanager
def point(x, y):
print('在yield之前')
yield x * y # yield出去的值赋给 as 后面的变量
print('在yield之后')
with point(3, 4) as p:
print('p',p)
'''
结果:
在yield之前
p 12
在yield之后
'''
A module implemented using open contextlib
@contextmanager
def my_open(path):
f = open(path, mode='w')
yield f # 把这个f 赋给as后面的变量
f.close()
with my_open('2.txt') as f:
f.write('我是你爹')