2016-07-09 2 views
1

Я пытаюсь понять collections.abc Исходный код.Непоследовательная реализация collections.abc

Давайте посмотрим на Hashable класса __subclasshook__ реализации:

@classmethod 
def __subclasshook__(cls, C): 
    if cls is Hashable: 
     for B in C.__mro__: 
      if "__hash__" in B.__dict__: 
       if B.__dict__["__hash__"]: 
        return True 
       break 
    return NotImplemented 

Здесь мы в первую очередь проверить, что есть свойство hash и чем проверить, что она имеет не-ложное значение. Эта логика также представлена ​​в классе Awaitable.

И AsyncIterable класс __subclasshook__:

@classmethod 
def __subclasshook__(cls, C): 
    if cls is AsyncIterable: 
     if any("__aiter__" in B.__dict__ for B in C.__mro__): 
      return True 
    return NotImplemented 

Здесь мы просто проверить, что есть __aiter___ собственности, и эта логика представлена ​​в любых других классах из этого пакета.

Есть ли причина для этой логической разницы?

ответ

3

__hash__ protocol явно позволяет отмечать класс как нераспашиваемый, установив __hash__ = None.

Если класс [...] хочет подавить хеш-поддержку, он должен включить в определение класса __hash__ = None.

Причина в том, что a == b всегда требует hash(a) == hash(b). В противном случае dict, set и аналогичные структуры данных ломаются. Если дочерний класс меняет __eq__ явно или иначе, это может быть больше недействительным. Таким образом, __hash__ может быть помечен как неприменимый.

+2

Это, однако, не объясняет, почему также «Awaitable» делает это. – Bakuriu

+0

@Bakuriu Я бы предположил, что это от копирования, видя, как «Awaitable» определяется сразу после «Hashable». В [docs] (https://docs.python.org/3.5/library/collections.abc.html#collections.abc.Awaitable) упоминается, что 'Awaitable' работает не всегда правильно, поэтому ABC не может быть завершена , Строго говоря, ничто не запрещает другим ABC делать проверку «Hashable» в любом случае. – MisterMiyagi

Смежные вопросы