出于某种原因,要捕获变量,比如
i
这里需要定义一个函数,然后调用它
不
捕获
我
并且,在调用时,使用3,即用于
我
.
是否有更好的方法来捕获变量?(没有像那些函数定义/调用那样多余的语法噪音)
class Node(object):
def __init__(self, value, next=None):
self.value = value
self.next = next
def __str__(self):
return str(self.value) + ',' + str(self.next)
def list2LinkedListFoldrImpPb(nums):
ret = {0:lambda x:x}
i = 0
for num in nums:
ret[i+1] = lambda rs: ret[i](Node(num, rs))#---- i NOT captured !!
i = i+1
return ret[i](None)
def list2LinkedListFoldrImp(nums):
ret = {0:lambda x:x}
i = 0
def setf(ret, i, num):
ret[i+1] = lambda rs: ret[i](Node(num, rs))
for num in nums:
setf(ret, i, num) #---- i captured !!
i = i+1
return ret[i](None)
print(list2LinkedListFoldrImpPb([5,4,1])) # maximum recursion depth exceeded !!!
print(list2LinkedListFoldrImp([5,4,1])) # works
解决方案
作为参考,正如重复链接中提到的那样,解决方案是确保列出所有要作为本地参数捕获的变量。
有
不
捕获体内,创建范围/环境(闭包的一部分)
只有
调用函数时(和默认值
论据
-我想这是通话的一部分-
是
捕获)
class Node(object):
def __init__(self, value, next=None):
self.value = value
self.next = next
def __str__(self):
return str(self.value) + ',' + str(self.next)
# Creating a function and calling it works
def list2LinkedListFoldrOK(nums):
ret = {0:lambda x:x}
i = 0
def setf(ret, i, num):
ret[i+1] = lambda rs: ret[i](Node(num, rs))
for num in nums:
setf(ret, i, num)
i = i+1
return ret[i](None)
#Pb : The i in each lambdas refers to the *last* value that i had in the scope it came from, i.e., 3
def list2LinkedListFoldrImpKO(nums):
ret = {0:lambda x:x}
i = 0
for num in nums:
ret[i+1] = lambda rs: ret[i](Node(num, rs))
i = i+1
return ret[i](None)
#Solution : List all captured variables as locals via default
def list2LinkedListFoldrImpOK2(nums):
ret = {0:lambda x:x}
i = 0
for num in nums:
ret[i+1] = lambda rs, i=i, num=num: ret[i](Node(num, rs))
i = i+1
return ret[i](None)
#Solution : or make an actual call
def list2LinkedListFoldrImpOK3(nums):
ret = {0:lambda x:x}
i = 0
for num in nums:
ret[i+1] = (lambda i,num: lambda rs: ret[i](Node(num, rs)))(i,num)
i = i+1
return ret[i](None)
print(list2LinkedListFoldrImpOK2([5,4,1]))
print(list2LinkedListFoldrImpOK3([5,4,1]))
print(list2LinkedListFoldrImp([5,4,1]))