Seite 1 von 1

Objekt explizit zerstören/löschen

Verfasst: Freitag 2. Februar 2007, 16:48
von tho.jo
Moin Moin,
ich will ein in Python erzeugtes Objekt explizit löschen, da es eine Funktion bereit stellt, die nur zur Lebenszeit des Objektes benötigt werden.
Ich will das stdout in einem Buffer umleiten und mache dies mit eben diesem Objekt. Bei dessen Zerstörung soll die Umleitung wieder aufgehoben werden.
Mit del obj oder obj= None wird der Destruktor nicht direkt ausgeführt. Das Objekt wir lediglich als "frei von Referenzen" markiert. Der GC löscht es erst am Ende...
Das Aufrufen von __delete()__ scheint mir ein wenig der falsche Ansatz zu sein. Es Funktioniert zwar, jedoch bekommt der GC diese "Löschung nicht mit, oder doch???

Ich zeig Euch mal den Code, wie das aussieht:

Code: Alles auswählen

class CCaptOutput(object):
    def __init__(self):
        print "Ctor"
        self.__buffer= []
        self.stdoutBackup= sys.stdout
        sys.stdout= self
    def __del__(self):
        print "Dtor"
        sys.stdout= self.stdoutBackup
    def write(self, text):
        self.__buffer.append(text)
    def getBuffer(self):
        return self.__buffer
    def printBuf(self):
        for l in self.__buffer:
            sys.__stdout__.write(l)

if __name__ == "__main__":
    print "Test this file " + __file__

    output = CCaptOutput()
    print "Hallo"
    buf= output.getBuffer()
    output.printBuf()
    del output
    print "buf ", buf
    print "End..."
Ausgabe:
Test this file /home/thc1nl/sdf_Backup/sdfGlobals.py
Ctor
Hallo
Dtor
Zur Erklärung:
An der Stell, an der "print "Hallo" steht, sollen später Befehle ausgeführt werden, deren Ausgabe am Bildschirm im Python-Programm verwendet werden sollen...

Verfasst: Freitag 2. Februar 2007, 16:56
von tho.jo
Dass der Destruktor erst am Programmende ausgeführt wird, kann man sehen, indem man noch eine Ausgabe mit

Code: Alles auswählen

sys.__stdout__.write(str)
anfügt:

Code: Alles auswählen

if __name__ == "__main__":
    print "Test this file " + __file__
    
    output = CCaptOutput()
    print "Hallo"
    buf= output.getBuffer()
    output.printBuf()
    del output
    print "buf ", buf
    sys.__stdout__.write("End...\n")
Ausgabe:
  • Test this file /home/thc1nl/sdf_Backup/sdfGlobals.py
    Ctor
    Hallo
    End..
    Dtor

Verfasst: Freitag 2. Februar 2007, 17:17
von tho.jo
ist vielleicht auch nicht ganz unwichtig:
Redhat Linux, python 2.3.4

Verfasst: Freitag 2. Februar 2007, 21:10
von BlackJack
Benenne die `__del__()`-Methode in `close()` um und ruf sie explizit auf. Und benutze `__del__()` am besten auch nicht. Damit gibt es letztendlich zu viele Probleme und zu wenige Garantien.

Ich würde übrigens `__del__()` genausowenig als Destruktor bezeichnen, wie ich zu `__init__()` Konstruktor sagen würde. Destruktoren gibt's in Python nicht und der Konstruktor heisst `__new__()`.

Verfasst: Freitag 2. Februar 2007, 21:10
von jens
ich würde nicht sys.__stdout__.write(l) machen, sondern erst den alten stdout wieder herstellen und dann normal den Buffer raus schreiben...