下面的代码抛出1
两次,我希望看到0
,然后1
def pv(v) :
print v
def test() :
value = []
value.append(0)
value.append(1)
x=[]
for v in value :
x.append(lambda : pv(v))
return x
x = test()
for xx in x:
xx()
我希望python lambdas绑定到一个局部变量在场景后面指向的引用。然而,情况似乎并非如此。我已经在一个大系统中解决这个问题,在这个系统中,lambda正在做一个绑定的现代C++(例如,Boosi::BIN),在这种情况下,你会绑定到一个智能的PTR或者拷贝为LAMBDA复制一个副本。
那么,如何将局部变量绑定到lambda函数并在使用时保留正确的引用?这种行为让我目瞪口呆,因为我不希望这种行为来自一种带有垃圾收集器的语言。
出现问题的代码如下所示(l3_e是导致问题的变量):
for category in cat :
for l2 in cat[category].entries :
for l3 in cat[category].entries[l2].entry["sub_entries"] :
l3_e = cat[category].entries[l2].entry["sub_entries"][l3]
url = "http://forums.heroesofnewerth.com/" + l3_e.entry["url"]
self.l4_processing_status[l3_e] = 0
l3_discovery_requests.append( Request(
url, callback = lambda response : self.parse_l4(response,l3_e)))
print l3_e.entry["url"]
return l3_discovery_requests
lambda的闭包保存对正在使用的变量的引用,而不是它的值,因此,如果变量的值稍后更改,闭包中的值也会更改。也就是说,闭包变量的值在调用函数时解析,而不是在创建函数时解析。(就其价值而言,Python在函数式编程领域的行为并不罕见。)
有两种解决方案:
使用默认参数,在定义时将变量的当前值绑定到本地名称。
lambda v=v: pv(v)
使用双羔羊,并立即调用第一个。
(lambda v: lambda: pv(v))(v)
将
x.append(lambda : pv(v))
更改为x.append(lambda v=v: pv(v))
。您希望“python lambdas绑定到本地变量在场景后面指向的引用”,但这不是python的工作方式。Python在调用函数时查找变量名,而不是在创建函数时查找。使用默认参数有效,因为默认参数是在创建函数时计算的,而不是在调用函数时计算的。
这不是兰姆达斯的特别之处。考虑:
印刷品
相关问题 更多 >
编程相关推荐