"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 중첩되지 않은 Lambda 클로저에서 변수 범위 문제를 처리하는 방법은 무엇입니까?

중첩되지 않은 Lambda 클로저에서 변수 범위 문제를 처리하는 방법은 무엇입니까?

2024-11-07에 게시됨
검색:230

How to Handle Variable Scoping Issues in Non-Nested Lambda Closures?

Python Lambda 클로저 범위 지정

문제

함수 서명에서 변수를 제거하기 위해 클로저 내에 변수를 캡슐화하는 것은 효율적인 코드 구조화에 자주 사용되는 기술입니다. 그러나 중첩되지 않은 람다의 경우 클로저는 변수의 최종 값을 유지하므로 반복 변수를 기반으로 특정 값에 액세스하려고 시도할 때 문제가 발생합니다.

제공된 코드 조각을 고려하세요.

names = ['a', 'b', 'c']

def test_fun(name, x):
    print(name, x)

def gen_clousure(name):
    return lambda x: test_fun(name, x)

funcs1 = [gen_clousure(n) for n in names]
funcs2 = [lambda x: test_fun(n, x) for n in names]

# Expected output for funcs1
for f in funcs1:
    f(1)

# Unexpected output for funcs2 (returns last element for all cases)
for f in funcs2:
    f(1)

이러한 불일치의 원인을 이해하는 것은 효과적인 클로저 활용에 매우 중요합니다.

답변

이 상황의 기본 개념은 클로저의 변수 범위 지정입니다. . 클로저는 본질적으로 대신 변수 이름을 보유합니다. 이는 람다 정의 시점이 아닌 람다 실행이 시작될 때 변수 평가가 발생한다는 것을 의미합니다.

funcs2의 경우 람다 x: test_fun(n, x)를 실행하면 변수 n 람다 정의 중에는 평가되지 않습니다. 대신 평가는 람다 호출 시에만 발생합니다. 이 시점에서 n은 루프의 마지막 값(이 경우 'c')을 보유합니다. 결과적으로 함수 f는 입력 x에 관계없이 항상 'c'를 n의 값으로 활용합니다.

이 문제를 해결하고 원하는 기능을 달성하려면 변수 n을 람다 함수의 범위에서 캡처해야 합니다. 이는 다음과 같이 변수를 인수로 전달하여 다음과 같이 달성할 수 있습니다.

funcs2 = [lambda x: test_fun(n, x) for n in names if 2 > 0]

항상 참인 추가 if 문을 포함함으로써 람다가 n 값을 인수로 취하도록 강제하여 모든 사례에서 예상되는 개인화된 동작을 보장합니다.

래핑된 람다를 사용한 대안

또는 중첩되지 않은 람다를 중첩 함수로 래핑하여 범위에서 선언되지 않은 변수에 대한 액세스를 효과적으로 방지할 수 있습니다. 다음 코드는 이 접근 방식을 보여줍니다.

def makeFunc(n):
    return lambda x: x n

stuff = [makeFunc(n) for n in [1, 2, 3]]

for f in stuff:
    print(f(1))

여기서 변수 n은 makeFunc 함수에 캡처되어 람다 내에서 적절한 범위 지정을 보장합니다.

결론

변수 범위 지정 이해 및 관리 효과적인 코드 디자인과 디버깅을 위해서는 클로저가 필수적입니다. 주요 내용은 다음과 같습니다.

  • 클로저는 값이 아닌 변수 이름을 보유합니다.
  • 람다 실행 중에 변수 평가가 발생합니다.
  • 변수를 캡처하려면 인수로 전달하거나 래핑하세요. 다른 함수의 람다
릴리스 선언문 이 글은 1729483641에서 재인쇄되었습니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3