Переопределение методов набора в Python - PullRequest
1 голос
/ 26 октября 2009

Я хочу создать пользовательский набор, который будет автоматически преобразовывать объекты в другую форму для хранения в наборе (см. Использование словаря Python в качестве не вложенного ключа ) для фона.

Если я переопределю add, remove, __contains__, __str__, update, __iter__, этого будет достаточно для правильной работы других операций, или мне нужно переопределить что-нибудь еще

Ответы [ 2 ]

7 голосов
/ 26 октября 2009

Работа с абстрактными классами collections, как предполагает @ kaizer.se, является подходящим решением в 2.6 (не знаю, почему вы хотите назвать super - какие функции вы пытаетесь делегировать, что не может быть лучше всего сделано сдерживанием, а не наследством?!).

Это правда, что вы не получаете update - предоставляя абстрактные методы, вы получаете __le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__, and isdisjoint (от collections.Set) плюс clear, pop, remove, __ior__, __iand__, __ixor__, and __isub__ (от collections.MutableSet), что намного больше, чем вы получите от подкласса set (где вам придется переопределить каждый интересующий метод). Вам просто нужно предоставить другие методы набора, которые вы хотите.

Обратите внимание, что абстрактные базовые классы, такие как collections.Set, довольно сильно отличаются от конкретных классов, включая встроенные функции, такие как set и (в 2.6) старый добрый sets.Set, не рекомендуется, но все еще существует (удалено в Python 3) , ABC предназначены для наследования (и могут затем синтезировать некоторые методы от вас, как только вы реализуете все абстрактные методы, как вам нужно) и, во-вторых, «регистрировать» классы, чтобы они выглядели так, как будто они унаследованы от них, даже если они этого не делают. (чтобы сделать isinstance более полезным и полезным).

Вот рабочий пример для Python 3.1 и 2.6 (нет веских оснований для использования 3.0, так как 3.1 имеет только преимущества над ним, без недостатков):

import collections

class LowercasingSet(collections.MutableSet):
  def __init__(self, initvalue=()):
    self._theset = set()
    for x in initvalue: self.add(x)
  def add(self, item):
    self._theset.add(item.lower())
  def discard(self, item):
    self._theset.discard(item.lower())
  def __iter__(self):
    return iter(self._theset)
  def __len__(self):
    return len(self._theset)
  def __contains__(self, item):
    try:
      return item.lower() in self._theset
    except AttributeError:
      return False
1 голос
/ 26 октября 2009

В Python 2.6:

import collections
print collections.MutableSet.__abstractmethods__
# prints:
# frozenset(['discard', 'add', '__iter__', '__len__', '__contains__'])

подкласс collections.MutableSet и переопределите методы в списке выше.

сам метод обновления очень прост, учитывая, что реализован минимум, указанный выше

def update(self, iterable):
    for x in iterable:
        self.add(x)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...