Вопрос

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

Если я переопределю add , remove , __ содержит __ , __str __ , update , __ iter __ , этого будет достаточно, чтобы другие операции работали правильно, или мне нужно переопределить что-нибудь еще?

Это было полезно?

Решение

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

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

Обратите внимание, что абстрактные базовые классы, такие как collection.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

Другие советы

В Python 2.6:

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

subclass collection.MutableSet и переопределите методы в приведенном выше списке.

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

def update(self, iterable):
    for x in iterable:
        self.add(x)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top