web-dev-qa-db-fra.com

comment supprimer le répertoire créé par python tempfile.mkdtemp

J'ai un programme python crée des répertoires tmp sous/temp en utilisant tempfile.mkdtemp.
Malheureusement, le programme python n'a pas supprimé le répertoire après l'avoir utilisé. Alors maintenant, l'espace disque est faible.

Des questions:

  1. Comment puis-je supprimer les répertoires temporaires laissés sous/temp manuellement? J'ai essayé de les supprimer manuellement, mais l'erreur "autorisation refusée" a été détectée.
  2. Dans le programme python, comment supprimer le répertoire temporaire après l’avoir utilisé.
31
Yesheng Li

Pour gérer les ressources (telles que les fichiers) en Python, il est recommandé d'utiliser le mot clé with, qui libère automatiquement les ressources (c'est-à-dire nettoie, comme pour fermer des fichiers). c'est disponible depuis Python 2.5.

A partir de Python 3.2, vous pouvez utiliser tempfile.TemporaryDirectory() au lieu de tempfile.mkdtmp() - ceci est utilisable dans with et nettoie automatiquement le répertoire:

from tempfile import TemporaryDirectory

with TemporaryDirectory() as temp_dir:
    # ... do something with temp_dir
# automatically cleaned up when context exited

Si vous utilisez une version antérieure de Python (au moins la version 2.5, donc with), vous pouvez utiliser backports.tempfile ; voir réponse de Nicholas Bishop à gestionnaire de contexte tempfichier.TemporaryDirectory dans Python 2.7 .

C’est facile et instructif de créer votre propre classe, appelée gestionnaire de contexte . La valeur de retour de la méthode __enter__() est liée à la cible de la clause as, tandis que la méthode __exit__() est appelée lorsque le contexte est quitté - même par exception - et effectue un nettoyage.

import shutil
import tempfile

class TemporaryDirectory(object):
    """Context manager for tempfile.mkdtemp() so it's usable with "with" statement."""
    def __enter__(self):
        self.name = tempfile.mkdtemp()
        return self.name

    def __exit__(self, exc_type, exc_value, traceback):
        shutil.rmtree(self.name)

Vous pouvez simplifier ceci avec le décorateur @contextlib.contextmanager, de sorte que vous n’aurez pas besoin d’écrire manuellement un gestionnaire de contexte. Le code précédant la yield est exécuté lors de la saisie du contexte, la valeur renvoyée est liée à la cible de la as et le code suivant la yield est exécuté lors de la sortie du contexte. Il s'agit fondamentalement d'une coroutine qui encapsule l'acquisition et la libération des ressources, la variable yield donnant le contrôle à la suite (corps) de la clause with. Notez qu'ici vous do devez disposer d'un bloc try...finally, car @contextlib.contextmanager n'intercepte pas les exceptions dans la yield - cela ne fait que factoriser la gestion des ressources dans un coroutine.

from contextlib import contextmanager
import tempfile
import shutil

@contextmanager
def TemporaryDirectory():
    name = tempfile.mkdtemp()
    try:
        yield name
    finally:
        shutil.rmtree(name)

Comme simplylizz note, si le répertoire déjà en cours de suppression n’a pas d’importance, le code ci-dessus ne suppose pas que cela se produit), vous pouvez capturer l’exception «Aucun fichier ou répertoire de ce type» comme suit:

import errno
# ...
try:
    shutil.rmtree(self.name)
except OSError as e:
    # Reraise unless ENOENT: No such file or directory
    # (ok if directory has already been deleted)
    if e.errno != errno.ENOENT:
        raise

Vous pouvez comparer avec l’implémentation standard dans tempfile.py ; même cette classe simple a eu des bugs et a évolué au fil des ans.

Pour plus d'informations sur with, voir:

59
Nils von Barth

Lisez la documentation , c'est simple. ;) À partir de la documentation: le répertoire est en lecture, en écriture et ne peut être recherché que par l'ID utilisateur qui crée.

Pour supprimer le répertoire temporaire, essayez quelque chose comme ceci:

import errno
import shutil
import tempfile

try:
    tmp_dir = tempfile.mkdtemp()  # create dir
    # ... do something
finally:
    try:
        shutil.rmtree(tmp_dir)  # delete directory
    except OSError as exc:
        if exc.errno != errno.ENOENT:  # ENOENT - no such file or directory
            raise  # re-raise exception

Aussi, vous pouvez essayer tempdir package ou voir ses sources.

28
simplylizz

Je pense que l'utilisateur est responsable de la suppression du répertoire temporaire et de son contenu créé à l'aide de tempfile.mkdtemp () . Il ne sera pas supprimé automatiquement, tout comme le fichier temporaire . Vous pouvez supprimer le répertoire de plusieurs façons.

Si le répertoire est vide, vous pouvez utiliser 

`os.removedirs or os.rmdir`

Notez qu’il ne peut être utilisé que si le répertoire est vide, sinon il sera déclenché 

OSError

Cela supprimera le chemin de répertoire complet:

import shutil    
shutil.rmtree('/path/to/your/dir/')

faites attention en utilisant ceci, il supprimera tout le répertoire et les fichiers qu'il contient. 

0
mohammed wazeem