Вопрос по python – Привязка Python к локальным значениям

46

Следующий код выплевывает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-лямбды будут привязываться к ссылке, на которую указывает локальная переменная, за сценой. Однако, похоже, это не так. Я столкнулся с этой проблемой в большой системе, где лямбда выполняет современный C ++ эквивалент эквивалента связывания (например, «boost :: bind»), где в таком случае вы будете привязываться к интеллектуальному ptr или копировать contstruct. копия для лямбды.

Итак, как мне связать локальную переменную с лямбда-функцией и сохранить ли она правильную ссылку при использовании? Я совершенно ошеломлен таким поведением, так как не ожидал бы этого от языка с сборщиком мусора.

Рассматриваемый код выглядит следующим образом (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
Я видел несколько вариантов этого вопроса. кто-то должен объединить их всех, изменить название на что-то запоминающееся, а затем сообщить в Интернет, чтобы Google Shep
ах, вот и ты, возле дубликата:lexical-closures-in-python Shep
@shep, да, я не могу правильно это сформулировать, я пытался воспроизвести способ работы lua. Hassan Syed
Error: User Rate Limit ExceededNameErrorError: User Rate Limit Exceeded BallpointBen
Error: User Rate Limit Exceeded Shep

Ваш Ответ

2   ответа
75

x.append(lambda : pv(v)) вx.append(lambda v=v: pv(v)).

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

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

печать

after foo was defined
Error: User Rate Limit ExceededvError: User Rate Limit ExceededintError: User Rate Limit ExceedednotError: User Rate Limit Exceeded
Error: User Rate Limit Exceededlambda par1, par2 = l3_e : self.parse_l4(par1, par2) ? Hassan Syed
Error: User Rate Limit Exceeded Hassan Syed
Error: User Rate Limit Exceededfunctools.partialError: User Rate Limit Exceededdef make_closure(v): return lambda: pv(v)Error: User Rate Limit Exceededtest).
16

Use a default argument, binding the current value of the variable to a local name at the time of definition. lambda v=v: pv(v)

Use a double-lambda and immediately call the first one. (lambda v: lambda: pv(v))(v)

Похожие вопросы