Друг привлек это к моему вниманию, и после того, как я указал на странность, мы оба смущены.
Документы Python, скажем, и сказали, по крайней мере, с 2.5.1 (еще не проверены далее:
Сравнение может быть скоблено произвольно, например, x < y <= z эквивалентно x < y и y <= z, за исключением того, что y оценивается только один раз (но в обоих случаях z вообще не оценивается, когда x < y считается ложным).
Наша путаница заключается в значении "y оценивается только один раз".
Учитывая простой, но надуманный класс:
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
Мы можем произвести этот результат:
>>> 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.
>>>
Это, конечно, выглядит так: "y" в традиционном смысле "оценивается" дважды - один раз при вызове x.__lt__(y)
и выполняет сравнение на нем, и один раз при вызове y.__le__(z)
.
Итак, имея в виду, что именно означают документы Python, когда говорят, что "y оценивается только один раз"?