스택큐힙리스트

람다 함수 클로저가 캡처하는 것은 무엇인가요? 본문

카테고리 없음

람다 함수 클로저가 캡처하는 것은 무엇인가요?

스택큐힙리스트 2023. 4. 22. 09:52
반응형

최근에 나는 파이썬을 조금 놀아보기 시작했고, 클로저의 작동 방식에서 특이한 것을 발견했다. 다음 코드를 생각해보자.

adders=[None, None, None, None]

for i in [0,1,2,3]:

adders[i]=lambda a: i+a

print adders[1](3)

그것은 단일 입력을 가져와 숫자가 추가된 입력을 반환하는 함수의 간단한 배열을 생성합니다. 이 함수들은 i a 이터레이터가 0!@ 에서 3 까지 실행되는 for 루프에서 구성됩니다. 각각의 숫자에 대해서, i a 를 캡처하여 입력값에 추가하는 lambda!@ 함수가 생성됩니다. 마지막 줄은 두 번째 lambda!@ 함수를 3 을 매개변수로 호출합니다. 놀랍게도 결과는 6 입니다.

내가 기대했던 것은 4 이었다. 이유는 파이썬에서 모든 것이 객체이기 때문에 모든 변수가 기본적으로 포인터임을 의미한다. l lambda 클로저를 i에 대해 생성할 때, 현재 i에서 가리키는 정수 객체에 대한 포인터를 저장할 것으로 예상했다. 즉, i가 새로운 정수 객체를 할당하면 이전에 생성된 클로저에 영향을 주지 않아야한다는 것을 의미한다. 안타깝게도 디버거 내에서 @#adders 배열을 검사하면 그렇지 않다는 것을 알 수 있다. 모든 l lambda 함수는 i의 마지막 값을 참조하므로 adders[1](3)는 6를 반환한다.

다음에 대해 생각하게 만든 것은 다음과 같습니다.

정확히 클로저는 무엇을 포착하나요?

$#@!&*@$&의 현재 값이 변경되어도 영향을 받지 않는 방식으로 lambda 기능을 설득하는 가장 우아한 방법은 무엇인가요?

Python에서 코드의 기본 동작을 이해하는 데 중점을 둔 이 질문은 루프(또는 리스트 내장, 생성기 표현식 등)가 사용된 경우에 특별히 적절하고 실용적인 질문 버전을 위해 Creating functions (or lambdas) in a loop (or comprehension)을(를) 참조하십시오.

Tkinter에서 버튼 만드는 문제를 해결하려고 이곳에 왔다면 더 구체적인 조언을 얻으려면 tkinter creating buttons in for loop passing command arguments을(를) 시도해보세요.

파이썬이 클로저를 어떻게 구현하는지의 기술적 세부사항은 What exactly is contained within a obj.__closure__?를 참조하십시오. 관련 용어 논의는 What is the difference between Early and Late Binding?를 참조하십시오.

답변 1

기본값인 인수를 사용하여 변수를 강제로 캡처할 수 있습니다:

>>> for i in [0,1,2,3]:

... adders[i]=lambda a,i=i: i+a # note the dummy parameter with a default value

...

>>> print( adders[1](3) )

4

아이디어는 매개 변수 (똑똑하게 이름을 지정한 i)를 선언하고 캡처하려는 변수의 기본값 (# $$^&** $$ &의 값)을 지정하는 것입니다.

답변 2

람다 함수 클로저는 무엇을 포착할까요?

람다 함수 클로저는 매우 강력한 개념입니다. 이를 이해하기 위해서는 함수, 변수범위와 클로저 등 기본적인 개념에 대해 이해해야 합니다. 람다 함수 클로저가 포착하는 것은 바로 함수가 생성된 시점의 상태입니다. 즉, 함수 내에서 접근 가능한 변수와 상수의 값이 포착됩니다.

람다 함수 클로저는 함수를 정의함으로써 생성됩니다. 함수가 정의된 시점에서, 그 함수가 접근 가능한 변수와 상수의 값이 모두 포착됩니다. 이후 함수가 호출될 때 클로저에 포착된 값이 사용됩니다.

람다 함수 클로저는 매우 유용한 개념입니다. 예를 들어, 함수가 다른 함수 내에서 실행될 때, 클로저를 사용하여 그 함수의 변수와 상수를 포착할 수 있습니다. 이는 함수를 보다 유연하게 사용할 수 있도록 도와줍니다.

람다 함수 클로저를 사용하면, 함수를 호출할 때마다 함수 내부의 변수와 상수의 값이 초기화되는 것이 아니라, 함수 정의 시점에서의 값을 사용하게 됩니다. 따라서, 같은 함수를 여러 번 호출할 때마다 같은 결과를 얻을 수 있습니다.

람다 함수 클로저는 자바스크립트 등의 프로그래밍 언어에서 널리 사용되는 개념입니다. 이 개념을 이해하면 함수를 보다 간결하고 유연하게 사용할 수 있으며, 코드의 가독성을 높일 수 있습니다. 따라서, 프로그래머들은 람다 함수 클로저에 대한 이해를 높여야 합니다.

반응형
Comments