it-swarm.com.de

so löschen Sie das von python erstellte Verzeichnis tempfile.mkdtemp

Ich habe ein Python-Programm erstellt tmp-Verzeichnisse unter/temp mithilfe von tempfile.mkdtemp.
Leider löschte das Python-Programm das Verzeichnis nach der Verwendung nicht. Jetzt ist der Speicherplatz niedrig.

Fragen:

  1. Wie lösche ich manuell die temporären Verzeichnisse unter/temp? Ich habe versucht, sie manuell zu löschen, bekam aber den Fehler "Erlaubnis verweigert".
  2. So löschen Sie im Python-Programm das temporäre Verzeichnis, nachdem Sie es verwendet haben.
31
Yesheng Li

Um Ressourcen (wie Dateien) in Python zu verwalten, empfiehlt es sich, das Schlüsselwort with zu verwenden, das die Ressourcen automatisch freigibt (d. H. Bereinigt, wie das Schließen von Dateien). Dies ist ab Python 2.5 verfügbar.

Ab Python 3.2 können Sie tempfile.TemporaryDirectory() anstelle von tempfile.mkdtmp() verwenden - dies ist in with verwendbar und bereinigt das Verzeichnis automatisch:

from tempfile import TemporaryDirectory

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

Wenn Sie eine frühere Version von Python verwenden (mindestens 2.5, also with), können Sie backports.tempfile verwenden. siehe Nicholas Bishop's answer to tempfile.TemporaryDirectory Kontextmanager in Python 2.7 .

Es ist einfach und aufschlussreich, eine eigene Klasse zu erstellen, die als context manager bezeichnet wird. Der Rückgabewert der __enter__()-Methode ist an das Ziel der as-Klausel gebunden, während die __exit__()-Methode aufgerufen wird, wenn der Kontext - auch ausnahmsweise - verlassen wird und eine Bereinigung durchführt.

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)

Sie können dies mit dem @contextlib.contextmanager-Dekorator vereinfachen, sodass Sie keinen Kontextmanager manuell schreiben müssen. Der Code vor der yield wird beim Eingeben des Kontexts ausgeführt, der erhaltene Wert ist an das Ziel der as gebunden, und der Code nach der yield wird beim Verlassen des Kontextes ausgeführt. Dies ist im Grunde eine Coroutine , die die Ressourcenerfassung und -freigabe einschließt, wobei die yield die Steuerung der suite (body) der with-Klausel übernimmt. Beachten Sie, dass Sie hier do über einen try...finally-Block verfügen müssen, da @contextlib.contextmanager keine Ausnahmen in der yield auffängt - dies berücksichtigt nur die Ressourcenverwaltung in einer Coroutine.

from contextlib import contextmanager
import tempfile
import shutil

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

Wenn Sie sich einfach nicht um das bereits gelöschte Verzeichnis kümmern (was im obigen Code nicht der Fall ist), können Sie wie simplelizz die Ausnahmebedingung "Keine Datei oder Verzeichnis" wie folgt abfangen:

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

Sie können die Standardimplementierung in tempfile.py vergleichen. Sogar diese einfache Klasse hatte Fehler und hat sich im Laufe der Jahre weiterentwickelt.

Hintergrundinformationen zu with finden Sie unter:

59
Nils von Barth

Lesen Sie die Dokumentation , es ist ganz einfach. ;) Aus den Dokumenten: Das Verzeichnis ist lesbar, schreibbar und nur durch die erstellende Benutzer-ID durchsuchbar.

So löschen Sie das temporäre Verzeichnis:

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

Sie können auch tempdir package ausprobieren oder die Quellen anzeigen.

28
simplylizz

Ich denke, der Benutzer ist dafür verantwortlich, das temporäre Verzeichnis und seinen Inhalt zu löschen, der mit tempfile.mkdtemp () ..__ erstellt wurde. Es wird nicht automatisch wie die temporäre Datei ..__ gelöscht. Es gibt viele Möglichkeiten, das Verzeichnis zu löschen

Wenn das Verzeichnis leer ist, können Sie verwenden 

`os.removedirs or os.rmdir`

Beachten Sie, dass es nur verwendet werden kann, wenn das Verzeichnis leer ist, andernfalls wird es erhöht 

OSError

Dadurch wird der gesamte Verzeichnispfad gelöscht:

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

seien Sie vorsichtig, wenn Sie dies verwenden. Das gesamte Verzeichnis und die darin enthaltenen Dateien werden gelöscht. 

0
mohammed wazeem

Ich hatte das gleiche/ähnliche Problem mit TemporaryDirectory (), das im Grunde die oben definierte Funktionalität abdeckt.

Mein Problem lag an der Verwendung des temporären Verzeichnisses. Früher habe ich den Inhalt durch Klonen eines Git-Repositorys aufgefüllt. Während des Vorgangs wurden schreibgeschützte Dateien erstellt, und bei einem normalen Beenden führten diese schreibgeschützten temporären Dateien dazu, dass das vollständige temporäre Verzeichnis dort blieb.

Hat das TemporaryDirectory an meine eigene Klasse geerbt und die Klassenmethode _cleanup mit dem folgenden Code überschrieben.

Der Code vor super () könnte optimiert sein, aber für mich war die Leistung nicht das Problem.

Ich habe die Kraft verwendet und die Quelle von " tempfile " gelesen.

import tempfile
import shutil
import stat 

class myTempDir(tempfile.TemporaryDirectory):
    @classmethod
    def _cleanup(self,name, warn_message):
        for root, dirs, files in os.walk(name):
            for fname in files:
                full_path = os.path.join(root, fname)
                os.chmod(full_path ,stat.S_IWRITE)
        super()

Die Lösung funktionierte für Windows 10 mit Python 3

0
Ali Avcı