Supponiamo di avere una classe che sembra vagamente simile a questa:
class Foo(object):
_value = None # XXX: see below
def __init__(self, value):
self._value = value
@property
def value(self):
"""The value of this Foo."""
return self._value
def __hash__(self):
return hash(self.value)
def __eq__(self, other):
return type(self) is type(other) and self.value == other.value
(So che la riga _value = None
è sbagliata, nel mio codice attuale _value
è un descrittore di dati con un valore predefinito. Non aumenta mai AttributeError
anche se non è stato ancora impostato, e I ' Sto solo cercando di emulare quel comportamento nel minor numero possibile di righe di codice. Potrei eliminare il comportamento, ma complicherebbe in modo significativo le cose in altre aree della mia base di codice.)
Ho violato le regole? Devo impostare _value
in Foo.__new__()
? Chiaramente deve essere impostato da qualche parte; ci sarà un punto nel tempo in cui cambia il hash()
della nostra istanza. Quando dovrebbe accadere, esattamente?
Se c'è non qualcosa di sbagliato con il codice sopra, allora perché il seguente codice è sbagliato? Logicamente, questa combinazione è illegale, ma non sono sicuro di quale classe abbia infranto le regole:
bar = set()
class Baz(object):
def __init__(self, *args, **kwargs):
bar.add(self)
super(Baz, self).__init__(*args, **kwargs) # play nice with MI
class Qux(Baz, Foo):
pass
assert Qux('quuux') in bar # assertion fires because the hash() changed