Азбука Python: регистрация против подклассов - PullRequest
5 голосов
/ 03 августа 2010

(я использую python 2.7) В документации по python указано, что вы можете передать отображение во встроенный dict, и оно скопирует это отображение в новый dict:

http://docs.python.org/library/stdtypes.html#mapping-types-dict

У меня есть класс, который реализует Азбуку сопоставления, но он не работает:

import collections
class Mapping(object):
    def __init__(self, dict={}): self.dict=dict
    def __iter__(self): return iter(self.dict)
    def __iter__(self): return iter(self.dict)
    def __len__(self): return len(self.dict)
    def __contains__(self, value): return value in self.dict
    def __getitem__(self, name): return self.dict[name]

m=Mapping({5:5})
dict(m)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: cannot convert dictionary update sequence element #0 to a sequence
collections.Mapping.register(Mapping)
dict(m)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: cannot convert dictionary update sequence element #0 to a sequence

Однако, если мои подклассы классов подобраны. Сопоставление тогда работает нормально:

import collections
class Mapping(collections.Mapping):
    def __init__(self, dict={}): self.dict=dict
    def __iter__(self): return iter(self.dict)
    def __iter__(self): return iter(self.dict)
    def __len__(self): return len(self.dict)
    def __contains__(self, value): return value in self.dict
    def __getitem__(self, name): return self.dict[name]

m=Mapping({5:5})
dict(m)
# {5: 5}

Я думал, что весь смысл ABC в том, чтобы регистрация работала так же, как и подклассы (в любом случае для isinstance и issubclass). Так что здесь?

Ответы [ 2 ]

8 голосов
/ 03 августа 2010

Регистрация не дает вам «отсутствующих методов», реализованных поверх тех, которые вы определили: на самом деле, регистрация неинвазивна относительно типа, который вы регистрируете - ничего не добавляется кэто, ничего не удаляется, ничто не изменяется.Он только влияет на isinstance и issubclass проверки: ни больше, ни меньше.

Создание подклассов ABC может и дает вам множество методов, реализованных "бесплатно" ABC наЛучшие из тех, что вы должны определить сами.

Семантика операции, которая полностью неинвазивна, как регистрация, по сравнению с операцией, которая предназначена для обогащения класса, напримерподклассы, очевидно, не могут быть идентичными;таким образом, ваше понимание «всей точки азбуки» несовершенно - азбука имеет две точки, одна получена путем подкласса («инвазивный»), одна - путем регистрации (неинвазивный).

Обратите внимание, что вы всегда можете многократно наследовать, если у вас уже есть класс, подобный вашему исходному Mapping: class GoogMapping(Mapping, collections.Mapping): ... даст вам те же результаты, что и наследование Mapping напрямую от collections.Mapping - новый тип все вспомогательные методы, добавленные collections.Mapping.

0 голосов
/ 03 августа 2010

Ах, похоже, что dict () ищет метод ключей ... Он не использует ABC.

...