Pregunta

Quiero crear un conjunto personalizado que convertirá automáticamente los objetos en una forma diferente para el almacenamiento en el conjunto (consulte Usar un diccionario de Python como clave no anidada ) para el fondo.

Si anulo add , remove , __contains__ , __str__ , update , __iter__ , ¿será eso suficiente para hacer que las otras operaciones se comporten correctamente, o debo anular algo más?

¿Fue útil?

Solución

Las clases abstractas de

Trabajar a partir de colecciones , como sugiere @ kaizer.se, es la solución adecuada en 2.6 (no estoy seguro de por qué quiere llamar super - ¿qué funcionalidad está intentando delegar? ¿No se puede hacer mejor por contención en lugar de por herencia ?!).

Es cierto que no obtiene update ; al proporcionar los métodos abstractos, obtiene __le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__, e isdisjoint (de collections.Set ) más clear, pop, remove, __ior__, __iand__, __ixor__, y __isub__ (de las colecciones de . MutableSet ), que es mucho más de lo que obtendría de la subclase set (donde tendría que anular todos los métodos de interés). Solo tendrás que proporcionar otros métodos de configuración que desees.

Tenga en cuenta que las clases base abstractas como collections.Set son una bestia bastante diferente de las clases concretas, incluidas las incorporadas como set y (en 2.6) good old sets.Set , en desuso pero todavía alrededor (eliminado en Python 3). Los ABC están destinados a heredar (y luego pueden sintetizar algunos métodos a partir de usted una vez que implemente todos los métodos abstractos, como debe) y, de forma secundaria, a " registrar " con las clases, por lo que parecen como si hubieran heredado de ellas incluso cuando no lo hacen (para hacer que isstance sea más útil y útil).

Este es un ejemplo práctico de Python 3.1 y 2.6 (no es una buena razón para usar 3.0, ya que 3.1 solo tiene ventajas sobre él, no tiene desventaja):

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

Otros consejos

En Python 2.6:

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

subclase collections.MutableSet y reemplaza los métodos en la lista anterior.

el método de actualización en sí es muy fácil, dado que se implementó el mínimo anterior

def update(self, iterable):
    for x in iterable:
        self.add(x)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top