2012-06-24 19 views
24

instacji pytona dict działa zgodnie z oczekiwaniami:Jak podklasować OrderedDict?

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

Jednak robi to samo z collections.OrderedDict nie działa:

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

Zatem realizacja OrderedDict wykorzystuje prywatny __root atribute, co zapobiega podklasa OrdDictSub zachowuje się jak podklasa DictSub. Czemu? Jak można dziedziczyć po OrderedDict?

+2

Dlaczego spadamy? – EOL

Odpowiedz

33

Trzeba powołać OrderedDict.__init__ ze swoimi __init__:

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

Nie dały OrderedDict szansę zainicjować sam. Z technicznego punktu widzenia chcesz to zrobić dla swojej podklasy dict, ponieważ chcesz w pełni zainicjować dict. Fakt, że dict działa bez niego, to tylko szczęście.

+0

Dzięki. Rzeczywiście moje. To prawda, że ​​byłem pod wpływem dyktatora. Nawet zadałem pytanie o dict jakiś czas temu (http://stackoverflow.com/questions/2033150/subclassing-dict-should-dict-init-be-called)! – EOL

+6

Nie chcesz, aby argumenty i kwargs w init? 'def __init __ (self, * args, ** kwargs): super (OrdDictSub, self) .__ init __ (* args, ** kwargs)' – hobs

2

Spróbuj inicjowania superklasę w metodzie __init__:

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

Jest to normalny sposób zainicjować podklasy. Nie musisz mieć, aby ogólnie zadzwonić do metody nadklasy __init__, ale jeśli nie masz wiedzy na temat implementacji superklasy, powinieneś zadzwonić pod numer __init__.

+1

Użyj 'super()' do wywołania metod nadklasy – astynax

+1

@astynax: Oba sposoby działają, więc to kwestia stylu. –

+9

@DietrichEpp: Dobra odpowiedź, ale użycie 'super()' nie jest kwestią stylu: ważne jest, aby go używać (zamiast używania jawnej nadklasy) w przypadku, gdy twoja klasa jest podklasowana. Przykładowy odnośnik: http://rhettinger.wordpress.com/2011/05/26/super-considered-super/. Ponadto użycie 'super()' sprawia, że ​​kod jest łatwiejszy w utrzymaniu (łatwiej jest zmienić nazwę klasy). – EOL

Powiązane problemy