2016-09-13 5 views
4

우리는 다중 상속을 사용하여 하찮게 OrderedCounter를 만들 수 있습니다 내가 틀렸다면왜 OrderedDict는 super를 사용하지 않습니까?

>>> from collections import Counter, OrderedDict 
>>> class OrderedCounter(Counter, OrderedDict): 
...  pass 
... 
>>> OrderedCounter('Mississippi').items() 
[('M', 1), ('i', 4), ('s', 4), ('p', 2)] 

저를 수정, 그러나 이것은 결정적으로 사실에 의존을하는 Counter uses super :

입니다
class Counter(dict): 
    def __init__(*args, **kwds): 
     ... 
     super(Counter, self).__init__() 
     ... 

, 마법

>>> OrderedCounter.__mro__ 
(__main__.OrderedCounter, 
collections.Counter, 
collections.OrderedDict, 
dict, 
object) 

super 호출 사이클로 작업하기 전에 형제 '에 따라 위임해야하기 때문에 트릭 작동 re 부모의 규칙은 mro이며, 사용자 정의 클래스는 저장 백엔드로 OrderedDict을 사용합니다. 처음에는

def __setitem__(self, key, value, 
       dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): 
    ... 
    # <some weird stuff to maintain the ordering here> 
    dict_setitem(self, key, value) 

내가 OrderedDict 먼저 와서 레이몬드 나중에 변경 귀찮게하지 않았기 때문에이 될 수 있다고 생각 :

그러나 동료는 최근 OrderedDict doesn't 사용 슈퍼 것을, 놀랍게도, 지적 하지만 super 이전에 OrderedDict 인 것으로 보입니다.

OrderedDict은 왜 dict.__setitem__입니까?

왜 kwarg가 필요합니까? 이것은 다이아몬드 상속 상황에서 OrderedDict을 사용할 때 문제를 일으키지 않습니까? mro에서 다음 행으로 위임하는 대신 상위 클래스로 직접 전달되기 때문입니다.

답변

0

미세 최적화입니다. dict_setitem 인수를 찾는 것은 dict.__setitem__ 또는 super().__setitem__을 찾는 것보다 약간 빠릅니다.

__setitem__을 덮어 쓰는 다른 클래스가있는 경우 다중 상속에 문제가 발생할 수 있지만 OrderedDict은 그런 종류의 다이아몬드 구조화 메서드를 재정의하도록 설계되지 않았습니다. OrderedDict을 지원하려면 순서 정보가 dict 구조와 일치하지 않는 동안 OrderedDict을 인덱싱하려고하면 다른 클래스의 메서드가 볼 수있는 정보를 매우주의 깊게 보장해야합니다. 그러한 보장은 너무 지저분해질 수 있습니다.

+0

Django의'QueryDict'는'__setitem__'을 오버라이드하고'collections.OrderedDict'는 협력 적 상속을하지 않습니다. 이 '미세 최적화'로 인해 발생하는 문제의 예 : https://stackoverflow.com/questions/23662247/can-i-make-django-querydict-preserve-ordering#comment78727560_41798570 – wim