2012-03-31 7 views
11

Raymond Hettinger showed eine wirklich coole Art Collection-Klassen zu kombinieren:Subklassen von OrderedDict und defaultdict

from collections import Counter, OrderedDict 
class OrderedCounter(Counter, OrderedDict): 
    pass 
# if pickle support is desired, see original post 

Ich möchte etwas ähnliches für OrderedDict und defaultdict tun. Aber natürlich hat defaultdict eine andere __init__ Signatur, so dass es zusätzliche Arbeit erfordert. Was ist der sauberste Weg, um dieses Problem zu lösen? Ich benutze Python 3.3.

Ich fand eine gute Lösung hier: https://stackoverflow.com/a/4127426/336527, aber ich dachte, vielleicht abgeleitet von defaultdict könnte dies noch einfacher machen?

+3

Während wir auf das Thema sind, kann mir jemand erklären, wie das OrderedDict Beispiel bekommt tatsächlich OrderedDict Funktionalität ohne explizite 'Super'-Delegation zu dieser Klasse? Liegt es an "Super" -Aufrufen irgendwo innerhalb von "Counter", die durch "OrderedDict" umgeleitet werden, anstatt direkt zu "dict" zu gehen, wie es normalerweise der Fall wäre? Oder nur was? –

+0

@KarlKnechtel Sie meinen 'OrderedCounter', aber gute Frage. – agf

+0

@agf er, ja, genau. Stupid edit timeout ... :( –

Antwort

7

Vererbung von OrderedDict wie in der Antwort, die Sie verknüpft haben, ist der einfachste Weg. Es ist mehr Arbeit, einen geordneten Speicher zu implementieren, als Standardwerte von einer Factory-Funktion zu erhalten.

Alles, was Sie für defaultdict implementieren müssen, ist ein bisschen benutzerdefinierte __init__ Logik und die extrem einfache __missing__.

Wenn Sie stattdessen von defaultdict erben, müssen Sie delegieren oder neu zu implementieren mindestens __setitem__, __delitem__ und __iter__ die in Ordnung Betrieb zu reproduzieren. Sie müssen noch Setup-Arbeiten in __init__ durchführen, obwohl Sie je nach Ihren Anforderungen möglicherweise einige der anderen Methoden erben oder einfach weglassen können.

Werfen Sie einen Blick auf the original recipe oder any of the others linked to from another Stack Overflow question für was das bedeuten würde.

3

Ich habe einen Weg gefunden, sie beide zu Unterklasse, aber nicht sicher, ob es Fehler:

class OrderedDefaultDict(defaultdict, OrderedDict): 
    def __init__(self, default, *args, **kwargs): 
     defaultdict.__init__(self, default) 
     OrderedDict.__init__(self, *args, **kwargs) 
+0

Macht das nicht zwei interne Wörterbücher? – leewz

+0

Oh, ich verstehe. Ich nur Lesen Sie den verlinkten Beitrag in der ursprünglichen Frage. – leewz