2012-03-31 5 views
11

Raymond Hettinger showed un modo davvero cool per combinare classi di insiemi:sottoclassi da OrderedDict e defaultdict

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

voglio fare qualcosa di simile per OrderedDict e defaultdict. Ma, naturalmente, defaultdict ha una diversa firma __init__, quindi richiede un lavoro extra. Qual è il modo più pulito per risolvere questo problema? Io uso Python 3.3.

Ho trovato una buona soluzione qui: https://stackoverflow.com/a/4127426/336527, ma stavo pensando che derivare da defaultdict potrebbe renderlo ancora più semplice?

+3

Visto che siamo in tema, qualcuno può spiegarmi come l'esempio OrderedDict in realtà ottiene funzionalità OrderedDict senza alcuna esplicita 'super'-delegazione in quella classe? È a causa di 'super' chiamate da qualche parte all'interno di' Counter' che vengono reindirizzati attraverso 'OrderedDict' invece di andare a' dict' direttamente come ordinariamente farebbero? O solo cosa? –

+0

@KarlKnechtel Intendi "OrderedCounter", ma buona domanda. – agf

+0

@agf er, si, esattamente. Stupid timeout di modifica ... :( –

risposta

7

Ereditare da OrderedDict come nella risposta a cui si è collegati è il modo più semplice. È più lavoro implementare un negozio ordinato piuttosto che ottenere valori predefiniti da una funzione di fabbrica.

Tutto ciò che è necessario implementare per defaultdict è un po 'di logica personalizzata __init__ e l'estremamente semplice __missing__.

Se invece si eredita dai defaultdict, è necessario delegare o re-implementare almeno __setitem__, __delitem__ e __iter__ per riprodurre il funzionamento in ordine. Devi ancora eseguire il lavoro di installazione in __init__, anche se potresti essere in grado di ereditare o semplicemente tralasciare alcuni degli altri metodi a seconda delle tue esigenze.

Dai un'occhiata a the original recipe o any of the others linked to from another Stack Overflow question per quello che ciò comporterebbe.

3

ho trovato un modo per creare una sottoclasse entrambi, ma non so se ci sono bug:

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

Questo non fa due dizionari interni? – leewz

+0

Oh, capisco. leggi il post collegato nella domanda originale. – leewz