Co oznacza „oceniany tylko raz” dla łańcuchowych porównań w Pythonie?

Mój przyjaciel zwrócił na to moją uwagę i po tym, jak wskazałem na dziwaczność, oboje jesteśmy zdezorientowani.

Python's docs, powiedzmy, od co najmniej 2.5.1 (nie sprawdzałem dalej:

Porównania można łączyć dowolnie, np. X <y <= z jest równoważne x <yi y <= z, z wyjątkiem tego, że y jest oceniane tylko raz (ale w obu przypadkach z nie jest w ogóle oceniane, gdy znaleziono x <y być fałszywym).

Nasze zamieszanie polega na znaczeniu „y jest oceniane tylko raz”.

Biorąc pod uwagę prostą, ale wymyślną klasę:

class Magic(object):
    def __init__(self, name, val):
        self.name = name
        self.val = val
    def __lt__(self, other):
        print("Magic: Called lt on {0}".format(self.name))
        if self.val < other.val:
            return True
        else:
            return False
    def __le__(self, other):
        print("Magic: Called le on {0}".format(self.name))
        if self.val <= other.val:
            return True
        else:
            return False

Możemy uzyskać ten wynik:

>>> x = Magic("x", 0)
>>> y = Magic("y", 5)
>>> z = Magic("z", 10)
>>> 
>>> if x < y <= z:
...     print ("More magic.")
... 
Magic: Called lt on x
Magic: Called le on y
More magic.
>>> 

To na pewnowygląda jak „y” jest, w tradycyjnym znaczeniu, „oceniany” dwa razy - raz, kiedyx.__lt__(y) jest wywoływany i wykonuje na nim porównanie i raz, gdyy.__le__(z) jest nazywany.

Mając to na uwadze, co dokładnie oznaczają dokumenty Pythona, gdy mówią, że „y jest oceniane tylko raz”?

questionAnswers(2)

yourAnswerToTheQuestion