2012-06-24 14 views
24

subclases de una pitón dict funciona como se espera:¿Cómo se subclase un OrderedDict?

>>> class DictSub(dict): 
...  def __init__(self): 
...   self[1] = 10 
...   
>>> DictSub() 
{1: 10} 

Sin embargo, hacer lo mismo con un collections.OrderedDict no funciona:

>>> import collections 
>>> class OrdDictSub(collections.OrderedDict): 
...  def __init__(self): 
...   self[1] = 10 
...   
>>> OrdDictSub() 
(…) 
AttributeError: 'OrdDictSub' object has no attribute '_OrderedDict__root' 

Por lo tanto, la aplicación OrderedDict utiliza un __root atributo privado, lo que impide la subclase OrdDictSub se comporta como la subclase DictSub. ¿Por qué? ¿Cómo se puede heredar de un OrderedDict?

+2

¿Por qué el voto a favor? – EOL

Respuesta

33

es necesario invocar OrderedDict.__init__ de su __init__:

class OrdDictSub(collections.OrderedDict): 
    def __init__(self): 
     super(OrdDictSub, self).__init__() 

No ha dado la oportunidad de OrderedDict inicializarse. Técnicamente, también debe hacer esto para su subclase dict, ya que desea un dict totalmente inicializado. El hecho de que dict funcione sin él es solo suerte.

+0

Gracias. Mi mal, de hecho. Es cierto que fui influenciado por Dict. Incluso hice una pregunta sobre dict hace algún tiempo (http://stackoverflow.com/questions/2033150/subclassing-dict-should-dict-init-be-llamado)! – EOL

+6

¿no quieres args y kwargs en init? 'def __init __ (self, * args, ** kwargs): super (OrdDictSub, self) .__ init __ (* args, ** kwargs)' – hobs

2

Intenta inicializar la superclase en el método __init__:

def __init__(self): 
    collections.OrderedDict.__init__(self) 
    self[1] = 10 

Esta es la manera normal para inicializar una subclase. Usted no tiene para llamar al método __init__ de la superclase en general, pero si no tiene conocimiento de la implementación de la superclase, debe llamar al __init__.

+1

Use 'super()' para llamar a los métodos de la superclase – astynax

+1

@astynax: Ambas formas funcionan, por lo que es una cuestión de estilo. –

+9

@DietrichEpp: Buena respuesta, pero usar 'super()' no es una cuestión de estilo: es importante usarlo (en lugar de usar una superclase explícita) en caso de que su propia clase esté subclasificada. Ejemplo de referencia: http://rhettinger.wordpress.com/2011/05/26/super-considered-super/. Además, usar 'super()' hace que el código sea más fácil de mantener (es más fácil cambiar el nombre de la clase). – EOL

Cuestiones relacionadas