program tip

Python 람다의 로컬 값 바인딩

radiobox 2021. 1. 7. 07:50
반응형

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()

나는 파이썬 람다가 현장 뒤에서 지역 변수가 가리키는 참조에 바인딩 할 것으로 예상했습니다. 그러나 그것은 사실이 아닌 것 같습니다. 나는 람다가 현대 C ++의 바인드 (예 : 'boost :: bind')를 수행하는 대형 시스템에서이 문제를 발견했습니다.이 경우 스마트 ptr에 바인드하거나 복사하여 람다에 대한 사본을 구성합니다.

그렇다면 지역 변수를 람다 함수에 바인딩하고 사용할 때 올바른 참조를 유지하려면 어떻게해야합니까? 나는 가비지 수집기가있는 언어에서 이것을 기대하지 않을 것이기 때문에 행동에 상당히 불만을 가지고 있습니다.

문제의 코드는 다음과 같습니다 (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

변경 x.append(lambda : pv(v))x.append(lambda v=v: pv(v)).

"파이썬 람다는 백그라운드에서 로컬 변수가 가리키는 참조에 바인딩 될 것"을 기대하지만 파이썬이 작동하는 방식은 아닙니다. Python은 함수가 생성 될 때가 아니라 호출 될 때 변수 이름을 조회합니다. 기본 인수를 사용하면 기본 인수가 함수가 호출 될 때가 아니라 생성 될 때 평가되기 때문에 작동합니다.

이것은 람다에 대해 특별한 것이 아닙니다. 중히 여기다:

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

인쇄물

after foo was defined

람다의 클로저는 값이 아니라 사용중인 변수에 대한 참조를 보유하므로 나중에 변수 값이 변경되면 클로저의 값도 변경됩니다. 즉, 클로저 변수의 값은 함수가 생성 될 때가 아니라 호출 될 때 해결됩니다. (여기서 Python의 동작은 함수형 프로그래밍 세계에서 드문 일이 아닙니다.)

There are two solutions:

  1. 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)

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

ReferenceURL : https://stackoverflow.com/questions/10452770/python-lambdas-binding-to-local-values

반응형