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.
Ist es auf einfache Art möglich herauszufinden wieviele Instanzen einer Klasse erstellt wurden ohne sie explizit bei der Erstellung zu zählen? Gut wäre auch noch die Instanz-Referenzen als Liste abrufen zu können.
Mir ist kein solcher Weg bekannt. Normalerweise packt man gleichartige Klassen in Container und das passt dann schon so. Ich fände es seltsam, wenn Instanzen je nach Anzahl bereits existierender Instanzen sich anders verhalten würden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Wenn es denn sowas wie statische Attribute gäbe... Ja, dann könnte man es zumindest zum Teil implementieren. Aber ich habe hier irgendwie mal gelesen, dass der destruktor von Python eigentlich gar keiner ist... Aber ich habe den noch nie wirklich benutzt.
Also gibt's keine statischen Variablen in Python?
Wieder was gelernt ;p
Aber man kann doch theoretisch innerhalb des Konstruktors eine Variable außerhalb der Klasse (globale Variable?) hochzählen, oder?
Wobei das natürlich keinen Sinn macht, wenn der Destruktor, wie BlackVivi sagte, nicht richtig funktioniert bzw. nicht dafür gedacht ist ;o
Aber dann kann man ja noch notfalls, wenn's nicht zu umständlich ist (keine Ahnung, um was es genau geht, daher kann ich das auch nicht sagen), jedes mal wenn man eine Instanz zerstört, den Wert wieder eins runtersetzen. Aber das geht dann auch wieder nur, wenn man die Instanzen selbstständig zerstört.
In [45]: a = int()
In [46]: global a
In [58]: class Foo(object):
....: def __init__(self):
....: global a
....: a += 1
....:
....: def __del__(self):
....: global a
....: a -= 1
....:
....:
In [59]: Foo()
Out[59]: <__main__.Foo object at 0x85d72cc>
In [60]: Foo()
Out[60]: <__main__.Foo object at 0x85d716c>
In [61]: a
Out[61]: 2
In [63]: Foo()
Out[63]: <__main__.Foo object at 0x85d736c>
In [64]: Foo()
Out[64]: <__main__.Foo object at 0x85d73cc>
In [65]: Foo()
Out[65]: <__main__.Foo object at 0x85d74ac>
In [66]: a
Out[66]: 5
In [67]: foo = Foo()
In [68]: a
Out[68]: 6
In [69]: foo = None
In [70]: a
Out[70]: 5
In [71]: liste = [Foo(), Foo()]
In [72]: a
Out[72]: 7
In [73]: liste = None
In [74]: a
Out[74]: 5
Wie unfassbar sinnfrei.
@veers
Die Dinger habe ich vorhin gesucht =_= Ich wusste das ich sie schonmal benutzt hatte, aber ich bin einfach zu lange raus und muss durch die Hochschule halt Java lernen... Da verdrängt man schnell mal ein paar Sachen. Ich bin so doof ~_~
Die Doku sagt dazu allerdings: "Avoid using get_referrers() for any purpose other than debugging."
Diese Warnung sollte man beherzigen. Wenn man eine Liste aller Instanzen einer Klasse braucht, dann sollte man das explizit über ein Klassenattribut und das Überschreiben des Konstruktors lösen.
Alles andere ist zu magisch und hat imho in sauberem Code nichts zu suchen!
BlackVivi, das ist keine gute Idee. Der Zeitpunkt an dem ``__del__`` aufgerufen wird ist in Python undefiniert. Vielleicht auch gar nicht, dann stimmt der Counter gar nicht mehr. Jetzt nehmen wir noch Threads dazu, die gleichzeitig ``a`` modifizieren und das Chaos ist komplett.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas hat geschrieben:BlackVivi, das ist keine gute Idee. Der Zeitpunkt an dem ``__del__`` aufgerufen wird ist in Python undefiniert. Vielleicht auch gar nicht, dann stimmt der Counter gar nicht mehr. Jetzt nehmen wir noch Threads dazu, die gleichzeitig ``a`` modifizieren und das Chaos ist komplett.
Jap, deswegen steht auch "VORSICHT GRAUSAM" davor :3 Und deswegen steht dazwischen auch einige Beispiele, wo __del__ scheinbar gar nicht in einem absehbaren Zeitraum aufgerufen wird... Wenn man es nämlich nie an einen Namen bindet. Wollte damit nur zeigen, dass __del__ fei doof ist, mehr nicht ._.
Lösungsmöglichkeit: In der `__init__()` eine schwache Referenz auf `self` in eine Liste stecken, die an die Klasse gebunden ist. Schwache Referenz -> `weakref`-Modul. Und wenn man wissen will wieviele Exemplare es gibt, dann schaut man einfach wieviele von den Referenzen noch "leben".
Die Vorgehensweise hat natürlich auch so ihre Nachteile. Zum Beispiel kann die Liste mit "toten" Referenzen lang werden und die Laufzeit der Abfrage der Anzahl ist nicht in O(1).
In [21]: sum(1 for obj in gc.get_objects() if isinstance(obj, str))
Out[21]: 12
In [22]: test = "some string"
In [23]: sum(1 for obj in gc.get_objects() if isinstance(obj, str))
Out[23]: 13
Testweise - Ja. Praktisch - vielleicht.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann