一位朋友提请我注意,在我指出一个奇怪之后,我们都感到困惑。
Python的文档说,至少从2.5.1开始说(还没有进一步检查过:
比较可以任意链接,例如,x <1。 y&lt; = z等于x&lt; y和y&lt; = z,除了y仅被评估一次(但在两种情况下,当x&lt; y被发现为假时,根本不评估z。)
我们的困惑在于“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.
>>>
这肯定看起来像x.__lt__(y)
并对其进行比较,一次{{} 1}}被称为。
因此,考虑到这一点,当他们说“y只被评估一次”时,Python文档究竟是什么意思?
答案 0 :(得分:44)
“表达式”y
评估一次。即,在下面的表达式中,该函数只执行一次。
>>> def five():
... print 'returning 5'
... return 5
...
>>> 1 < five() <= 5
returning 5
True
相反:
>>> 1 < five() and five() <= 5
returning 5
returning 5
True
答案 1 :(得分:8)
在y被评估的上下文中,y表示可能具有副作用的任意表达式。例如:
class Foo(object):
@property
def complain(self):
print("Evaluated!")
return 2
f = Foo()
print(1 < f.complain < 3) # Prints evaluated once
print(1 < f.complain and f.complain < 3) # Prints evaluated twice