1. ¿Qué es un administrador de contexto?
A menudo vemos el siguiente código cuando procesamos archivos, que es el administrador de contexto:
with open('test.txt', encoding='utf-8') as f:
print(f.readlines())
Su significado es abrir el archivo test.txt en el directorio actual e imprimir su contenido, que es lo mismo que el siguiente código:
f = open('test.txt', encoding='utf-8')
print(f.readlines())
f.close()
Al comparar los dos métodos de escritura, se puede encontrar que usar este paso de with
ejecución automática f.close()
(cerrar el archivo) puede escribir un poco menos de código.
A continuación se explica cómo implementar dicho administrador de contexto.
Directorio de artículos
2. Cómo implementar un administrador de contexto
1. Implementado por clase
Si queremos implementar open
la función de administrador de contexto anterior, podemos crear una clase y agregar __enter__
métodos __exit__
, como se muestra en el siguiente código:
class DiyOpen(object):
def __init__(self, filename, **kwargs):
self.f = open(filename, **kwargs)
def __enter__(self):
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print('关闭文件')
self.f.close()
with DiyOpen('test.txt', encoding='utf-8') as f:
print(f.readlines())
resultado de salida
['第一行\n', '第二行\n', '第三行']
关闭文件
Se puede ver que después de que imprimimos el contenido del archivo, la operación de cerrar el archivo se realiza automáticamente.
¿Cuál es el significado de la __enter__
suma y cuál es el significado de la segunda ?__exit__
__exit__
exc_type, exc_val, exc_tb
1)_ entrar _
__enter__
En términos relativos, es más fácil de entender, cuando aparece la instrucción with, se activará, cuando haya un valor de retorno, el valor de retorno se asignará a la variable declarada as
, que es la que tenemos arriba as f
.f
2)_ salida _
__exit__
Se ejecuta automáticamente después de que se completa la ejecución con. El significado de los parámetros detrás de él es el siguiente:
- exc_type: tipo de excepción
- exc_val: motivo de excepción
- exc_tb: información de seguimiento de la pila
Cuando el código ejecutado en with reporta un error, además de no continuar ejecutando el código contenido en with, el mensaje de error también se colocará en los tres parámetros anteriores, como el siguiente código:
class DiyOpen(object):
def __init__(self, filename, **kwargs):
self.f = open(filename, **kwargs)
def __enter__(self):
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type)
print(exc_val)
print(exc_tb)
self.f.close()
with DiyOpen('test.txt', encoding='utf-8') as f:
print(f.no())
resultado de salida
<class 'AttributeError'>
'_io.TextIOWrapper' object has no attribute 'no'
<traceback object at 0x000002A34B834900>
hay que tener en cuenta es:
- Podemos especificar manualmente
__exit__
el valor de retorno de True para que no informe de un error. - Cuando no hay información de excepción, los valores de los tres parámetros anteriores serán Ninguno
2. Implementado a través de contextlib
Python tiene un contextlib
módulo incorporado para implementar administradores de contexto, se implementa a través de generadores yield
, este módulo nos evita tener que crear clases y __entrar__ y __salir__.
El contextlib
código que implementa la función open es el siguiente:
from contextlib import contextmanager
@contextmanager
def diy_open(filename, **kwargs):
f = open(filename, **kwargs) # __init__
try:
yield f # __enter__
finally: # __exit__
f.close()
with diy_open('test.txt', encoding='utf-8') as f:
print(f.readlines())
¡Bienvenido a suscribirse a la nueva columna "Construyendo una plataforma de prueba automatizada desde 0" !
Dirección de demostración en línea de la plataforma: http://121.43.43.59/ (Cuenta: admin Contraseña: 123456)