Warum ruft a == b auf b .__ EQ__, wenn er von der Liste abgeleitet ist und mit fehlender Überschrift ein Tupel abgeleitePython

Python-Programme
Anonymous
 Warum ruft a == b auf b .__ EQ__, wenn er von der Liste abgeleitet ist und mit fehlender Überschrift ein Tupel abgeleite

Post by Anonymous »

Hintergrund
Ich schreibe Mathematik -Dienstprogrammklassen ListVector und tupleVector ,
Erben aus der Liste bzw. Tuple :

Code: Select all

class ListVector(list):
...

class TupleVector(tuple):
...
< /code>
(Abgesehen davon: Ich behaupte nicht unbedingt, dass dies wirklich eine gute Idee ist; in der Tat,
bin ich mir bewusst, dass ich dies wohl nicht tun sollte, da meine beabsichtigten Beziehungen logisch "has-a"-"-"-"-als" is-a ",

und unangemessenes Basspflichten, das von dem Basis-AS-AS-AS-AS-AS-AS-AS-AS-AS-AS-AS-AS-AS-ASS-ASS-ASS-ASS-ASS-ASS-ASS-ASS-ASS-ASS-ASS, ist, wenn es nicht gefährlich ist, wenn es nicht gefährlich ist. Meine
Klassen, z. />  [url=viewtopic.php?t=14917]Ich möchte[/url] den Vergleich von ListVector < /code> gegen TupleVector < /code> verwenden. Ich möchte, dass dies erfolgreich ist: < /p>
  assert ListVector((1,2,3)) == TupleVector((1,2,3))
< /code>
Beachten Sie, dass sich dies vom Verhalten der Basisklasse unterscheidet: < /p>
  assert list((1,2,3)) != tuple((1,2,3))
< /code>
i.e.
  assert [1,2,3] != (1,2,3)
Ich muss daher die __eq __ und __ne __ in meinen beiden Vektorklassen überschreiben. Klasse,
Aber ich habe zunächst vergessen, sie in meinem ListVector < /code> Klasse zu implementieren.

Code: Select all

  assert ListVector((1,2,3)) == TupleVector((1,2,3))  # unexpectedly succeeds!
Erwartete Verhalten: Da ich vergessen habe, __eq __ und __ne __ In ListVector zu überschreiben, erwarte ich, dass der Aufruf von == Call zum Auflisten fällt .__ EQ __ , was false ,
und so dass der Assprüger fehlschlägt. Verhalten: Aufrufe reflektierter TupleVector .__ EQ __ Stattdessen,
, was true zurückgibt, und so ist die Behauptung erfolgreich! LIST .__ EQ __ < /code>? < /p>
Nach den hier beschriebenen Regeln
(was aus dieser FAQ entnommen wird),
Ich denke, es sollte die Liste nennen .__ EQ __ < /code>. überschrieben __eq __ (dh type (a) .__ EQ __ ist kein Objekt .__ EQ __ ), dann ist das Ergebnis a .__ EQ __ (b) . /> < /blockquote>
Mein Lesen der Dokumentation scheint auch zu der gleichen Schlussfolgerung zu führen wie die FAQ (dh die Methode des linken Operanden, d. H. List .__ Gl. __ < /code>, sollte aufgerufen werden): < /p>

Wenn der Operand den Operand der Operand der Operands von der richtigen Art und Oper von unterschiedlichem Operand ist, ist der Typ. Typ, die reflektierte Methode des rechten Operand

Code: Select all

#!/usr/bin/python3

class ListVector(list):
# OOPS! Forgot to implement __eq__ and __ne__ for ListVector
# ...
pass

class TupleVector(tuple):
def __eq__(self, other):
print("TupleVector.__eq__ called")
# strict=True so comparing Vectors of unequal length will throw
return all(x==y for x,y in zip(self,other, strict=True))
def __ne__(self, other):
return not self.__eq__(other)
# ...

# Unit test
assert repr(ListVector((1,2,3))) == "[1, 2, 3]"  # succeeds as expected
assert repr(TupleVector((1,2,3))) == "(1, 2, 3)"  # succeeds as expected
assert TupleVector((1,2,3)) == ListVector((1,2,3))  # emits "TupleVector.__eq__ called" and succeeds, as expected
assert ListVector((1,2,3)) == TupleVector((1,2,3))  # WTF: unexpectedly emits "TupleVector.__eq__ called" and succeeds!

# Confirm that the condition "type(a).__eq__ isn’t object.__eq__", mentioned
# in the decision procedure in the FAQ, holds:
assert ListVector.__eq__ is list.__eq__  # because I forgot to override that
assert ListVector.__eq__ is not object.__eq__  # because list.__eq__ is not object.__eq__
assert TupleVector.__eq__ is not tuple.__eq__  # because I remembered that override
assert TupleVector.__eq__ is not object.__eq__  # definitely not
< /code>
Die (überraschende) Ausgabe ist: < /p>
TupleVector.__eq__ called
TupleVector.__eq__ called
< /code>
Ich habe das stattdessen erwartet, "TupleVector.__eq__ called< /code> "sollte
nur einmal statt zweimal emittiert werden,
und der"assert ListVector((1,2,3)) == TupleVector((1,2,3))
"sollte fehlschlagen.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post