一尘不染

Python Lambda绑定到本地值

python

以下代码吐出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 ++的bind等效操作(例如’boost :: bind’),在这种情况下,你将绑定到智能ptr或copy构造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

阅读 350

收藏
2020-02-21

共1个答案

一尘不染

更改x.append(lambda : pv(v))x.append(lambda v=v: pv(v))

你可能希望“ python lambdas在后台绑定到本地变量指向的引用”,但这不是Python的工作方式。Python在调用函数时(而不是在创建函数时)查找变量名。使用默认参数是可行的,因为默认参数是在创建函数时(而不是在调用函数时)求值的。

这对于lambdas而言并不特殊。考虑:

x = "before foo defined"
def foo():
    print x
x = "after foo was defined"
foo()

输出:

after foo was defined
2020-02-21