Seite 1 von 2
alle instanzen einer klasse auflisten
Verfasst: Montag 5. Februar 2007, 12:39
von netzmensch
hi,
wie kann ich alle instanzen/objekte einer klasse herausfinden? ich habe eine dynamische zahl an instanzen, weiß also nicht um wie viele es sich handelt. jede dieser instanzen hat eine "update"-funktion, die ich ja irgendwie aufrufen muss--> dies geht aber nur, wenn ich eine auflistung aller instanzen habe. oder gibt es einen anderen lösungsansatz?
mfg, der netzmensch
Verfasst: Montag 5. Februar 2007, 13:26
von Rebecca
Da musst du halt eine Liste mitfuehren, die alle Instanzen enthaelt. Das koennte man z.B als statische Variable der Klasse machen, die bei jedem __init__ erweitert wird...
Verfasst: Montag 5. Februar 2007, 14:03
von N317V
Ich stand vor dem gleichen Problem und hab mir zu diesem Zweck einen ObjectManager geschrieben, dem ich eine Klasse übergebe und der mir eine Instanz davon erzeugt und eine Referenz darauf zurückgibt. Eine Art universelle Factory-Klasse. Intern speichert er die Instanz in einem Dictionary, das auch die Klasse und inzwischen noch diverse andere nützliche Informationen enthält. Der Lösungsansatz ist also ganz ähnlich, wie der von Rebecca, nur noch ein bisschen aufgebohrt.
Verfasst: Montag 5. Februar 2007, 16:24
von Luzandro
Damit wird dann allerdings auch der Speicher für die Objekte nicht mehr automatisch freigegeben, da immer eine Referenz darauf existiert - du musst die Objekte also auch wieder explizit aus dieser Liste entfernen, wenn sie nicht mehr gebraucht werden.
gc
Verfasst: Montag 5. Februar 2007, 16:31
von sunmountain
Code: Alles auswählen
import gc
class A:
pass
a,b,c,d = [ A() for x in xrange(4) ]
print gc.get_referrers(A)
plus ein bischen extra Code,
aber eine komplette Lösung wäre ja langweilig ...
Verfasst: Montag 5. Februar 2007, 17:06
von netzmensch
sauber! genau das was ich gesucht habe! danke!
der Vollständigkeit halber ...
Verfasst: Montag 5. Februar 2007, 17:49
von sunmountain
Code: Alles auswählen
import gc
class A:
pass
a,b,c,d = [ A() for x in xrange(4) ]
for r in gc.get_referrers(A):
if isinstance(r,A):
print r
was dazu führt:
<__main__.A instance at 0x008E23A0>
<__main__.A instance at 0x008E23C8>
<__main__.A instance at 0x008E23F0>
<__main__.A instance at 0x008E2418>
Eine Factory-Klasse wird hier also nicht benötigt.
Verfasst: Montag 5. Februar 2007, 18:08
von N317V
Python ist viel zu leicht.
Hab jetzt ehrlich gesagt noch nicht in der Doku nachgesehen, aber krieg ich über den gc auch die Namen, also a, b, c, und d?
So
Verfasst: Montag 5. Februar 2007, 22:43
von sunmountain
N317V hat geschrieben:Python ist viel zu leicht.
Hab jetzt ehrlich gesagt noch nicht in der Doku nachgesehen, aber krieg ich über den gc auch die Namen, also a, b, c, und d?
Code: Alles auswählen
import gc
class A:
pass
a,b,c,d = [ A() for x in xrange(4) ]
for r in gc.get_referrers(A):
if type(r) is dict:
for k in r.keys():
if isinstance(r[k],A):
print k
Verfasst: Montag 5. Februar 2007, 22:47
von birkenfeld
netzmensch hat geschrieben:sauber! genau das was ich gesucht habe! danke!
Als sauber würde ich das nicht bezeichnen. Den GC betrachte ich eher als Implementationsdetail, auf den ich mich nicht verlassen will.
Verfasst: Montag 5. Februar 2007, 22:49
von birkenfeld
N317V hat geschrieben:Python ist viel zu leicht.
Hab jetzt ehrlich gesagt noch nicht in der Doku nachgesehen, aber krieg ich über den gc auch die Namen, also a, b, c, und d?
Da hat wieder jemand das Konzept von Namen und Objekten nicht ganz verstanden.
Code: Alles auswählen
a = b = c = A()
d = {}
d['x'] = A()
e = [A(), A(), A()]
So, was sind jetzt die Namen?
Merke: Namen sind Schall und Rauch und keine Objekteigenschaft.
Und da wir alle Menschen sind ...
Verfasst: Montag 5. Februar 2007, 22:56
von sunmountain
birkenfeld hat geschrieben:
Da hat wieder jemand das Konzept von Namen und Objekten nicht ganz verstanden.
... geben wir den Dingen gerne Namen.
Es ist schon klar, das es mit anonymen Objekten so nicht geht.
Die "reine" Lehre ist nur so lange gut, wie sie nutzt.
Verfasst: Dienstag 6. Februar 2007, 09:36
von netzmensch
birkenfeld hat geschrieben:netzmensch hat geschrieben:sauber! genau das was ich gesucht habe! danke!
Als sauber würde ich das nicht bezeichnen. Den GC betrachte ich eher als Implementationsdetail, auf den ich mich nicht verlassen will.
und was würdest du dann als alternative bezeichnen?
Verfasst: Dienstag 6. Februar 2007, 09:45
von N317V
Doch, ich denke schon, dass ich das verstanden hab. Die Namen in Deinem Beispiel sind a, b, c, d, e und natürlich A. Wenn ich keinen Namen kenne, wie sprech ich dann jemanden an bzw. wie kapiert irgendwer, wen ich angesprochen habe? Ich kann natürlich auch irgendetwas in den freien Raum brüllen und hoffen, dass sich schon der Richtige angesprochen fühlt. Solche Programmierkonzepte hab ich auch schon gesehen. Find ich auch ganz spannend. Kann mir aber nicht vorstellen, dass Du so in Python programmierst.
Verfasst: Dienstag 6. Februar 2007, 17:22
von Leonidas
N317V hat geschrieben:Die Namen in Deinem Beispiel sind a, b, c, d, e und natürlich A.
Nein, ``A`` ist ein Klassenobjekt, kein Instanzobjekt (und ich glaube danach war gefragt). Und an den Namen ``e`` ist eine List-Klasse gebunden.
Verfasst: Dienstag 6. Februar 2007, 17:59
von N317V
Richtig! Und die beiden Klassenobjekte heißen A bzw. e (auch wenn das nicht unbedingt zur Ausgangsfrage gehört, aber das hatte er ja nicht gefragt). Die Frage ist doch aber: ist eine Referenz auf ein Objekt eine Einbahnstraße? Kann ich, wenn ich ein Objekt habe, rausfinden, wo oder von wem oder wie es referenziert wird? Gerade der gc müsste sowas doch können, oder? Teilweise geht es ja, wie schon gezeigt wurde.
Hatten wir nicht schonmal so eine Diskussion mit der Frage, ob die Schachtel weiß in welcher Schublade sie steckt? Gut die Schachtel scheint es in diesem Fall nicht zu wissen, weil es ja keine Objekteigenschaft ist, aber vielleicht kann man es trotzdem irgendwie rausfinden. Ich schau mir den gc nochmal an. Ich wüsste nicht, warum ich Skrupel haben sollte den einzusetzen.
Verfasst: Dienstag 6. Februar 2007, 18:10
von birkenfeld
netzmensch hat geschrieben:birkenfeld hat geschrieben:
Als sauber würde ich das nicht bezeichnen. Den GC betrachte ich eher als Implementationsdetail, auf den ich mich nicht verlassen will.
und was würdest du dann als alternative bezeichnen?
So etwas z.B.:
Code: Alles auswählen
class A(object):
instances = []
def __new__(cls, *args, **kwds):
instance = object.__new__(cls, *args, **kwds)
A.instances.append(instance)
return instance
Verfasst: Dienstag 6. Februar 2007, 18:19
von birkenfeld
N317V hat geschrieben:Richtig! Und die beiden Klassenobjekte heißen A bzw. e (auch wenn das nicht unbedingt zur Ausgangsfrage gehört, aber das hatte er ja nicht gefragt). Die Frage ist doch aber: ist eine Referenz auf ein Objekt eine Einbahnstraße? Kann ich, wenn ich ein Objekt habe, rausfinden, wo oder von wem oder wie es referenziert wird? Gerade der gc müsste sowas doch können, oder? Teilweise geht es ja, wie schon gezeigt wurde.
Das kannst du ja auch machen. Nur es dazu zu missbrauchen, irgendwelche Namen von Objekten herauszufinden, ist sinnlos, gerade weil diese Namen immer nur im Kontext eines bestimmten Namensraums gültig sind. Andere Objekte haben, wie demonstriert, gar keinen Namen.
Jetzt versuch mal herauszubekommen, was "a" ist. Innerhalb des Modulnamensraumes ist es eine Liste, innerhalb des Namensraumes von "x" ein Dict. Und ganz wo anders wiederum... etc.
Dein vorhin geposteter Code funktioniert z.B. nur mit Instanzen, die im selben Modul-Namensraum wie die Klasse definiert werden.
(*) Ja, ich weiß, dass man Instanzen von object nicht einfach Attribute zuweisen kann, das spielt aber hier keine Rolle.
Hatten wir nicht schonmal so eine Diskussion mit der Frage, ob die Schachtel weiß in welcher Schublade sie steckt? Gut die Schachtel scheint es in diesem Fall nicht zu wissen, weil es ja keine Objekteigenschaft ist, aber vielleicht kann man es trotzdem irgendwie rausfinden. Ich schau mir den gc nochmal an. Ich wüsste nicht, warum ich Skrupel haben sollte den einzusetzen.
Ihn für seinen Zweck einzusetzen ist sinnvoll. Ihn für etwas einsetzen zu wollen, was sinnlos ist, ist sinnlos.
Verfasst: Mittwoch 7. Februar 2007, 10:14
von N317V
birkenfeld hat geschrieben:
Jetzt versuch mal herauszubekommen, was "a" ist.
Andersrum, ich hab <list object at 0x011493C8> und will wissen wie darauf referenziert wird und die Antwort ist ja wohl ganz klar: a und x.b
Verfasst: Mittwoch 7. Februar 2007, 10:17
von birkenfeld
N317V hat geschrieben:birkenfeld hat geschrieben:
Jetzt versuch mal herauszubekommen, was "a" ist.
Andersrum, ich hab <list object at 0x011493C8> und will wissen wie darauf referenziert wird und die Antwort ist ja wohl ganz klar: a und x.b
Diese Antwort programmatisch zu geben, wird dir aber schwerfallen.