Ich schreibe eine Funktion, die ein großes Argument braucht, und läuft für eine lange Zeit. Es braucht das Argument nur zur Hälfte. Gibt es eine Möglichkeit für die Funktion, den Wert zu löschen, auf den das Argument verweist, wenn es keine Referenzen mehr gibt?So löschen Sie ein Funktionsargument frühzeitig?
konnte ich es, sobald die Funktion zurückkehrt, wie diese erhalten gelöscht:
def f(m):
print 'S1'
m = None
#__import__('gc').collect() # Uncommenting this doesn't help.
print 'S2'
class M(object):
def __del__(self):
print '__del__'
f(M())
Diese Drucke:
S1
S2
__del__
ich brauche:
S1
__del__
S2
Ich war auch versuchen def f(*args):
und def f(**kwargs)
, aber es hat nicht geholfen, ich bekomme immer noch __del__
zuletzt.
Bitte beachten Sie, dass mein Code auf der Tatsache basiert, dass Python Referenzzählung hat, und __del__
wird aufgerufen, sobald die Referenzzahl eines Objekts auf Null fällt. Ich möchte, dass der Referenzzähler eines Funktionsarguments in der Mitte einer Funktion auf Null fällt. Ist das möglich?
Bitte beachten Sie, dass ich dieses Problem zu umgehen wissen: eine Liste von Argumenten übergeben:
def f(ms):
print 'S1'
del ms[:]
print 'S2'
class M(object):
def __del__(self):
print '__del__'
f([M()])
Diese Drucke:
S1
__del__
S2
Gibt es eine Möglichkeit die frühe Löschung zu erhalten, ohne die API zu ändern (zB Einführung von Listen zu den Argumenten)?
Wenn es schwierig ist, eine tragbare Lösung zu erhalten, die in vielen Python-Implementierungen funktioniert, ich brauche etwas, die 2.7 in der jüngsten CPython funktioniert. Es muss nicht dokumentiert werden.
Warum wollen Sie das tun wollen? Generell denke ich, dass Python nicht Müll etwas sammeln, sobald es Referenzzählwert Hits 0, aber erst einige Zeit nach (nicht definiert). Sie sollten in der Lage sein, eine Speicherbereinigung zu erzwingen. – syntonym
Das Argument wird in von dem Anrufer Umfang weitergegeben. Letztendlich wird das Objekt dort immer noch referenziert.Wenn Sie die Ref-Anzahl in Ihrer Funktion jedoch so niedrig setzen, dass die Funktion das Objekt beendet, wird wahrscheinlich kein Garbage Collection-Vorgang ausgeführt, da die Referenzen des übergeordneten Bereichs noch nicht bereinigt sind. - Das ist größtenteils nur eine Vermutung, ich weiß nicht, wie sich das Verhalten zwischen 'foo (m)' und 'foo (M()) 'unterscheiden würde; Logik diktiert es * sollte nicht * unterscheiden, aber das ist auch abhängig von der Implementierung. – deceze
Ich * möchte * sagen, dass, selbst wenn Sie das Argument lösen, es noch außerhalb des Funktionsumfangs existiert. –