2013-05-26 2 views
2

함수의 목록 나는 예를 들어, 함수의 배열을 가지고, 그들에게 전화람다 함수와 파이썬

>>> i=0 
>>> x=lambda: c[i]() 
>>> i+=1 
>>> y=lambda: c[i]() 

: 그리고

>>> def f(): 
...  print "f" 
... 
>>> def g(): 
...  print "g" 
... 
>>> c=[f,g] 

그런 다음 나는 두 개의 람다 함수를 만들려고 :

>>> x() 
g 
>>> y() 
g 

이유 람다 C [I]은 동일? 람다 함수가 런타임에 전역 변수 i의 값을 가져 오는 때문이다

+0

이 문제를 해결하는 _easy_ 방법은 처음에 쓸모없는'lambda's을 생성하지 않는 것입니다. 이 두 줄을'x = c [i]'와'y = c [i]'로 대체하면 원하는 함수를 정확하게 얻을 수 있습니다. 'f' 대신에'lambda : f()'를 쓰는 유일한 이유는'f'를 클로저 네임 스페이스에 붙이면 나중에 그것을 사용하는 대신 나중에 찾을 수 있기 때문입니다. 당신은 여기에서 그것을하고 싶지 않습니다. 사실 그것은 정확히 당신의 문제를 일으키는 원인입니다. – abarnert

답변

10
+0

참고 : 링크 된 질문에 대해 허용되는 대답은 원하는 이름 캡처를 수행하는 방법을 보여줍니다 (http://stackoverflow.com/a/2295368/25050의 끝에있는 'createAdder' 함수 참조). –

3

실제 값을 캡처하지 않지만, 대신 :

>>> i = 0 
>>> x=lambda z = i : c[z]() #assign the current value of `i` to a local variable inside lambda 
>>> i+=1 
>>> y =lambda z = i : c[z]() 
>>> x() 
f 
>>> y() 
g 

A는 읽을 수 있어야합니다 그들은 네임 스페이스를 캡처합니다. 따라서 함수 내에서 i을 사용하면 실제로는 둘러싼 범위에서 검색됩니다. 그리고 그 값은 이미 바뀌 었습니다.

이 모든 것을 확인할 필요가 없습니다. lambda과이 목록을 참조하십시오.

>>> x = 1 
>>> def f(): 
... print(x) 
... 
>>> x = 2 
>>> def g(): 
... print(x) 
... 
>>> g() 
2 
>>> f() 
2