Automatische Relationen

Code-Stücke können hier veröffentlicht werden.
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich fand es häßlich, Relationen zwischen Eltern und Kindern explizit hinzuschreiben, wie in folgendem Fall:

Code: Alles auswählen

class Container:
    def __init__(self):
        self.items = []

    def add_item(self, item):
        self.items.append(item)
        item.parent = self

    def remove_item(self, item):
        self.items.remove(item)
        item.parent = None
Also habe ich mir folgende allgemeine Lösung überlegt:

Code: Alles auswählen

class ListRelation(object):
    def __init__(self, parent, child_attr=None):
        self.parent, self.child_attr = parent, child_attr
        self.children = []

    def add(self, child):
        self.children.append(child)
        self.set_child_attr(child, self.parent)
            
    def remove(self, child):
        self.children.remove(child)
        self.se_child_attr(child, None)
        
    def __len__(self):
        return len(self.children)
        
    def __iter__(self):
        return iter(self.children)
        
    def __getitem__(self, index):
        return self.children[index]
        
    def __setitem__(self, index, value):
        self.set_child_attr(self.children[index], None)
        self.children[index] = value
        self.set_child_attr(value, self.parent)
            
    def __delitem__(self, index):
        self.set_child_attr(self.children[index], None)
        del self.children[index]

    def set_child_attr(self, child, parent):
        if self.child_attr: setattr(child, self.child_attr, parent)
        
    def filter(self, fn):
        return (child for child in self.children if fn(child))
Und schon wird meine Container-Klassen-Implementierung "viel" kürzer:

Code: Alles auswählen

class Container:
    def __init__(self):
        self.items = ListRelation(self, 'parent')
Gute Idee?
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Wieso überhaupt noch so? Ich würde die Klasse Container von ListRelation erben lassen, dann habe ich Methoden die mir die Zugriffe auf meine Relation (die hald dann children heisst) gesichert. Ausserdem kann ich dann ja gleich mit self[3] auf die items zugreiffen. Die Implementierung und der Zugriff muss mich dann gar nicht mer kümmern.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

sma hat geschrieben:Gute Idee?
In Zeile 12 ist ein NameError. Mich würde allerdings ein konkreter Anwendungszweck schon interessieren.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

DasIch hat geschrieben:
sma hat geschrieben:Gute Idee?
In Zeile 12 ist ein NameError. Mich würde allerdings ein konkreter Anwendungszweck schon interessieren.
Wohl eher ein AttributeError, da

Code: Alles auswählen

self.se_child_attr(child, None)

Code: Alles auswählen

self.set_child_attr(child, None)
lauten müsste
Antworten