alle instanzen einer klasse auflisten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
netzmensch
User
Beiträge: 11
Registriert: Montag 5. Februar 2007, 12:36

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
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

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...
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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.
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

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.
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

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 ...
netzmensch
User
Beiträge: 11
Registriert: Montag 5. Februar 2007, 12:36

sauber! genau das was ich gesucht habe! danke!
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

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.
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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?
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

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
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

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.
netzmensch
User
Beiträge: 11
Registriert: Montag 5. Februar 2007, 12:36

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?
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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.
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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.
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.

Code: Alles auswählen

a = []
b = {}
x = object() # (*)
x.a = b
x.b = a
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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

birkenfeld hat geschrieben:

Code: Alles auswählen

a = []
b = {}
x = object() # (*)
x.a = b
x.b = a
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
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

N317V hat geschrieben:
birkenfeld hat geschrieben:

Code: Alles auswählen

a = []
b = {}
x = object() # (*)
x.a = b
x.b = a
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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten