JensDiemer

Wenn man Daten in Form eines Dictionaries speichern möchte, dazu aber ein paar spezielle Methoden benötigt, kann man eine eigene Klasse aufbauen und von dict erben. Wie man das macht, kann man im Beispiel sehen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class MeinDict(dict):
    def __init__(self, *args, **kwargs):
        """
        Die ursprüngliche Methode kann man über super() ansprechen. Allerdings
        hat das den Nachteil, dass man den verwendeten Klassennamen einfügen
        muss. Wenn man die Klasse umbenennt muss man alle super()-Aufrufe
        abändern.
        """
        print "init..."
        super(MeinDict, self).__init__(*args, **kwargs)

    def __setitem__(self, key, value):
        """
        Ohne super() kann man die geerbte Method über das 'dict'-Objekt
        ansprechen.
        """
        print "Neuer Eintrag %s = %s" % (key, value)
        dict.__setitem__(self, key, value)

    def update(self, d):
        """
        Man kann natürlich auch einfach eine Methode komplett selber nachbauen.
        Damit es Sinn macht, verändern wir den Wert in diesem Beispiel.
        """
        print "Daten mit %s per Hand updaten self.__setitem__()" % d
        for k, v in d.iteritems():
            self.__setitem__(k, "|%s|" % v)

    def pop(self, key):
        """
        Wenn man versehentlich die geerbte Methode falsch anspricht, entsteht
        ein ungewollter Loop, weil nicht die ursprüngliche Methode, sondern die
        eigene genutzt wird, die wiederrum sich selber Aufruft usw.
        """
        print "Eintrag '%s' herrauslösen" % key
        # Falsch:
        #return self.pop(key) # RuntimeError: maximum recursion depth exceeded

        return dict.pop(self, key) # richtig

    def as_tuple(self):
        """
        Hier definieren wir mal eine komplett eigene Methode. Dabei wird direkt
        auf die Dict-Einträge mit "self" zugegriffen.
        """
        print "Liefert alle Einträge als Tupel zurück"
        return self.items()


d = MeinDict({"a": 1})
print d # {'a': 1}

print "-" * 79

d["b"] = 2
print d # {'a': 1, 'b': 2}

print "-" * 79

d.update({"a": 5, "foo": "bar"})
print d # {'a': '|5|', 'b': 2, 'foo': '|bar|'}

print "-" * 79

print d.pop("b") # 2

print "-" * 79

print d.as_tuple() # [('a', '|5|'), ('foo', '|bar|')]

Ausgaben:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
init...
{'a': 1}
-------------------------------------------------------------------------------
Neuer Eintrag b = 2
{'a': 1, 'b': 2}
-------------------------------------------------------------------------------
Daten mit {'a': 5, 'foo': 'bar'} per Hand updaten self.__setitem__()
Neuer Eintrag a = |5|
Neuer Eintrag foo = |bar|
{'a': '|5|', 'b': 2, 'foo': '|bar|'}
-------------------------------------------------------------------------------
Eintrag 'b' herrauslösen
2
-------------------------------------------------------------------------------
Liefert alle Einträge als Tupel zurück
[('a', '|5|'), ('foo', '|bar|')]