一位朋友引起了我的注意,在我指出一个奇怪之后,我们都很困惑.
比方说,Python的文档已经说过至少2.5.1(还没有进一步检查:
比较可以任意链接,例如,x <y <= z等于x <y和y <= z,除了y仅被评估一次(但在两种情况下,当x <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
Run Code Online (Sandbox Code Playgroud)
我们可以产生这样的结果:
>>> 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.
>>>
Run Code Online (Sandbox Code Playgroud)
这肯定看似 'y',在传统意义上"评估"两次 - 一次x.__lt__(y)被调用并对其进行比较,一次y.__le__(z)被调用.
因此,考虑到这一点,当他们说"y仅被评估一次"时,Python文档究竟是什么意思?
Mat*_*son 44
'表达式' y被评估一次.即,在以下表达式中,该函数仅执行一次.
>>> def five():
... print 'returning 5'
... return 5
...
>>> 1 < five() <= 5
returning 5
True
Run Code Online (Sandbox Code Playgroud)
相反:
>>> 1 < five() and five() <= 5
returning 5
returning 5
True
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3757 次 |
| 最近记录: |