Um die Instanzen einer Klasse zu erfassen, habe ich das nachfolgende Script erstellt.
Leider finde ich nicht den Fehler, der zu folgender Meldung führt:
AttributeError: 'Kind' object has no attribute '_instances'
Könntet Ihr mir bitte helfen?
import datetime
import weakref
_instances = set()
class Kind:
def __init__(self, varname, vorname, nachname, geburtstag):
self.varname = varname
self.vorname = vorname
self.nachname = nachname
self.geburtstag = geburtstag
self._instances.add(weakref.ref(self))
def alter(self):
today = datetime.date.today()
alter = today.year - self.geburtstag.year
if today < datetime.date(today.year, self.geburtstag.month, self.geburtstag.day):
alter -= 1
return alter
@classmethod
def getinstances(cls):
x = set()
for ref in cls._instances:
obj = ref()
if obj is not None:
yield obj
else:
x.add(ref)
cls._instances -= x
janpeter = Kind(
'janpeter',
'Jan-Peter',
'Schneider',
datetime.date(1981, 10, 28)
)
katrin = Kind(
'katrin',
'Katrin',
'Schneider',
datetime.date(1983, 9, 16)
)
robert = Kind(
'robert',
'Robert',
'Schneider',
datetime.date(1986, 4, 28)
)
stefan = Kind(
'stefan',
'Stefan',
'Schneider',
datetime.date(1995, 3, 7)
)
for obj in Kind.getinstances():
print(obj.varname)
Instanzen einer Klasse erfassen / auflisten
Was ist ein Varname? Warum willst Du überhaupt alle Instanzen wissen? Entweder Du hast eine Liste mit Instanzen, die Du für einen bestimmten Zweck brauchst, oder nicht. Bei Dir also alle Kinder in eine Liste packen und gut ist.
_instances sollte ein Klassenattribut sein und vom Typ WeakSet. getinstances ist dann überflüssig.
_instances sollte ein Klassenattribut sein und vom Typ WeakSet. getinstances ist dann überflüssig.
Vielen Dank für die prompte Antwort. Ich hätte gern alle Instanzen im nachhinein abgegriffen, auch wenn sie mal ergänzt werden, um dann über das vollständige Set iterieren zu können, auch wenn es mal mehr werden (was nicht für Kinder gilt, das ist nur ein Übungsbeispiel)
Eine vollständige Auflistung aller Instanzen soll letztendlich genau das absichern, was Du als Voraussetzung beschrieben hast: Die prinzipiell vorher - aber nicht immer - vorhandene (vollständige) Liste. Es geht mir um die Frage: Habe ich aller meiner Kontakte als Instanzen erfasst? Und wenn nicht: wer fehlt?
Du versuchst die ganz offensichtlich mit _instances in die Klasse zu bringen. Und die gehört da nicht hin.
Eine Klasse bildet ein Objekt ab. Die Liste musst du da führen, wo die Instanzen erstellt werden, bzw. dort wo sie "aufgehoben" werden müssen. Das ist nicht in der Klasse. Das Design ist kaputt.
Eine Klasse bildet ein Objekt ab. Die Liste musst du da führen, wo die Instanzen erstellt werden, bzw. dort wo sie "aufgehoben" werden müssen. Das ist nicht in der Klasse. Das Design ist kaputt.
Kaputt hin oder her: Meine Kontakte habe ich in verschiedenen Listen - teilweise auf Papier. Und zukünftig habe ich sie als Instanzen. Und jetzt möchte ich sicher sein, dass ich alle Kontakte instantiiert habe. Und dafür brauche ich eine Zusammenstellung aller Instanzen. Damit ich anschließend in meinen Ursprungs-Kontaktlisten aushaken kann.
Das geht, ist aber selten eine gute Idee:
Wie Du siehst, kann nun der Garbage Collector nicht mehr greifen und Du erzeugst potentielle Speicherlecks. Besser ist es, Instanzen außerhalb der eigenen Klasse zu verwalten. Das macht auch den Code besser verständlich:
In tests sind auch hier alle Deine Instanzen, die Du dann auf Papier abhaken kannst.
Code: Alles auswählen
class Test:
instances = list()
def __init__(self):
self.__class__.instances.append(self)
def __repr__(self):
return 'id: {}'.format(id(self))
tests = [Test() for _ in range(5)]
del tests
for item in Test.instances:
print(item)
Code: Alles auswählen
class Test:
def __repr__(self):
return 'id: {}'.format(id(self))
tests = [Test() for _ in range(5)]
for item in tests:
print(item)
Wo ist denn jetzt dein Problem die Instanzen in eine Liste zu packen?
Ich verstehe deine Sorgen nicht.
Ob du die nun auf Papier oder auf Steintafeln hast ist doch völlig egal für die Lösung.
Spätestens wenn du die speichern willst, musst du sie ja auch wieder laden. Und dort wo du sie lädst, packst du sie halt in eine Liste.
Ich verstehe deine Sorgen nicht.
Ob du die nun auf Papier oder auf Steintafeln hast ist doch völlig egal für die Lösung.
Spätestens wenn du die speichern willst, musst du sie ja auch wieder laden. Und dort wo du sie lädst, packst du sie halt in eine Liste.
Code: Alles auswählen
import datetime
class Kind:
def __init__(self, varname, vorname, nachname, geburtstag):
self.varname = varname
self.vorname = vorname
self.nachname = nachname
self.geburtstag = geburtstag
def alter(self):
today = datetime.date.today()
alter = today.year - self.geburtstag.year
if today < datetime.date(today.year, self.geburtstag.month, self.geburtstag.day):
alter -= 1
return alter
def main():
kinder = []
kinder.append(Kind('janpeter','Jan-Peter','Schneider',
datetime.date(1981, 10, 28)))
kinder.append(Kind('katrin','Katrin','Schneider',
datetime.date(1983, 9, 16)))
kinder.append(Kind('stefan','Stefan','Schneider',
datetime.date(1995, 3, 7)))
kinder.append(Kind('stefan','Stefan','Schneider',
datetime.date(1995, 3, 7)))
for kind in kinder:
print(kind.vorname)
if __name__ == "__main__":
main()
Ich verstehe nicht, wo die Kontakte denn an unterschiedlichen Stellen erzeugt werden sollen? Im Programmcode gibt es meist nur eine Stelle, an der etwas generiert wird, egal aus was. DAAD mit den Abgleich verstehe ich auch nicht. Mit was willst du denn vergleichen.
Ich habe die Befürchtung, Du verwechselst ein Programm mit einem Notizzettel, wo ungeordnet was notiert wird. Kannst Du genauer beschrieben, was Du vorhast?
@kbr: deshalb verwendet der OP ja weakref.
Ich habe die Befürchtung, Du verwechselst ein Programm mit einem Notizzettel, wo ungeordnet was notiert wird. Kannst Du genauer beschrieben, was Du vorhast?
@kbr: deshalb verwendet der OP ja weakref.