tempfile namedtemporaryfile example python destructor temporary-directory

python - namedtemporaryfile - tempfile ruby



Manera correcta de limpiar una carpeta temporal en la clase Python (4)

Advertencia: nunca puede garantizar que la carpeta temporal se eliminará, ya que el usuario siempre puede detener el proceso y no puede ejecutar nada más.

Dicho esto, hacer

temp_dir = tempfile.mkdtemp() try: <some code> finally: shutil.rmtree(temp_dir)

Dado que esta es una operación muy común, Python tiene una manera especial de encapsular "hacer algo, ejecutar código, limpiar": un administrador de contexto . Puedes escribir el tuyo de la siguiente manera:

@contextlib.contextmanager def make_temp_directory(): temp_dir = tempfile.mkdtemp() try: yield temp_dir finally: shutil.rmtree(temp_dir)

y usarlo como

with make_temp_directory() as temp_dir: <some code>

(Tenga en cuenta que esto utiliza el @contextlib.contextmanager directo @contextlib.contextmanager para crear un administrador de contexto. Si desea implementar uno de la manera original, debe crear una clase personalizada con los métodos __enter__ y __exit__ ; el __enter__ crearía y devolvería el directorio temporal y el __exit__ eliminarlo.

Estoy creando una clase en la que quiero generar un espacio de trabajo temporal de carpetas que persistirán durante la vida útil del objeto y luego se eliminarán. Estoy usando tempfile.mkdtemp () en la definición de inicio para crear el espacio, pero he leído que no puedo confiar en que se llame a.

Estoy queriendo algo como esto:

class MyClass: def __init__(self): self.tempfolder = tempfile.mkdtemp() def ... #other stuff def __del__(self): if os.path.exists(self.tempfolder): shutil.rmtree(self.tempfolder)

¿Hay otra / mejor manera de manejar esta limpieza? Estaba leyendo sobre ''con'' pero parece que solo es útil dentro de una función.


Como lo indicó Bluewind , debe asegurarse de envolver la parte de rendimiento del administrador de contexto dentro de un intento: finalmente, de lo contrario, las excepciones no se manejarán correctamente dentro del administrador de contexto.

Desde Python 2.7 documentos

En el punto donde el generador cede, se ejecuta el bloque anidado en la instrucción with. El generador se reanuda después de salir del bloque. Si se produce una excepción no controlada en el bloque, se vuelve a cargar dentro del generador en el punto donde ocurrió el rendimiento. Por lo tanto, puede usar una sentencia try ... except ... finally para interceptar el error (si existe), o asegurarse de que se realice una limpieza. Si se atrapa una excepción simplemente para registrarla o realizar alguna acción (en lugar de suprimirla por completo), el generador debe volver a generar esa excepción. De lo contrario, el administrador de contexto del generador indicará a la instrucción with que la excepción se ha manejado, y la ejecución se reanudará con la instrucción inmediatamente después de la instrucción with.

Además, si estás usando Python 3.2+, deberías ver esta pequeña joya que tiene todo lo anterior bien envuelto para ti.

tempfile.TemporaryDirectory (sufijo = '''', prefijo = ''tmp'', dir = Ninguno)

Esta función crea un directorio temporal utilizando mkdtemp () (los argumentos proporcionados se pasan directamente a la función subyacente). El objeto resultante se puede utilizar como administrador de contexto (consulte Con administradores de contexto de instrucciones). Al completar el contexto (o la destrucción del objeto de directorio temporal), el directorio temporal recién creado y todo su contenido se eliminan del sistema de archivos.

El nombre del directorio se puede recuperar del atributo de nombre del objeto devuelto.

El directorio se puede limpiar explícitamente llamando al método cleanup ().

Nuevo en la versión 3.2.


Otra alternativa que usa contextlib es hacer que su objeto se pueda cerrar y usar el administrador de contexto de closing .

class MyClass: def __init__(self): self.tempfolder = tempfile.mkdtemp() def do_stuff(): pass def close(self): if os.path.exists(self.tempfolder): shutil.rmtree(self.tempfolder)

Luego con el gestor de contexto:

from contextlib import closing with closing(MyClass()) as my_object: my_object.do_stuff()


Una buena manera de lidiar con archivos y directorios temporales es a través de un administrador de contexto. Así es como puede usar tempfile.TemporaryFile o tempfile.NamedTemporaryFile : una vez que haya salido de la declaración with (mediante la salida normal, el retorno, la excepción o cualquier otra cosa), el archivo / directorio y su contenido se eliminarán del sistema de archivos.

Para Python 3.2+, esto está incorporado como tempfile.TemporaryDirectory :

import tempfile with tempfile.TemporaryDirectory() as temp_dir: ... do stuff ...

Para versiones anteriores de Python, puede crear fácilmente su propio administrador de contexto para hacer exactamente lo mismo. Las diferencias aquí de la respuesta de @katrielalex son el paso de args a mkdtemp() y el bloque try / finally para asegurarse de que el directorio se limpie si se produce una excepción.

import contextlib import shutil @contextlib.contextmanager def temporary_directory(*args, **kwargs): d = tempfile.mkdtemp(*args, **kwargs) try: yield d finally: shutil.rmtree(d) # use it with temporary_directory() as temp_dir: ... do stuff ...

Tenga en cuenta que si su proceso es difícil de kill -9 (por ejemplo, kill -9 ), los directorios no se limpiarán.