루프의 Lambda: 기본 클로저 매개변수 이해
Python 프로그래밍에서 람다 함수는 동적 코드를 생성하는 데 사용할 수 있는 익명 함수입니다. 블록. 그러나 루프에서 람다를 사용하면 예상치 못한 동작이 발생할 수 있습니다. 이 문서에서는 문제를 살펴보고 해결 방법을 제공합니다.
다음 코드 조각을 고려하세요.
# directorys == {'login': <object at ...>, 'home': <object at ...>} for d in directorys: self.command["cd " + d] = (lambda: self.root.change_directory(d))
목표는 명령을 함수에 매핑하는 사전 self.command를 만드는 것입니다. 각 함수는 디렉터리를 디렉터리에 지정된 값으로 변경해야 합니다. 그러나 결과는 예상치 못한 것입니다.
# Expected: self.command == { "cd login": lambda: self.root.change_directory("login"), "cd home": lambda: self.root.change_directory("home") } # Result: self.command == { "cd login": lambda: self.root.change_directory("login"), "cd home": lambda: self.root.change_directory("login") # <- Why login? }
루프에서 생성된 람다 함수가 동일한 클로저를 공유하기 때문에 문제가 발생합니다. d가 루프에서 업데이트되면 모든 람다 함수에 영향을 주어 동일한 변수를 참조하게 됩니다.
해결책: 기본 클로저 매개변수 사용
이 문제를 해결하려면 , 기본 클로저 매개변수를 도입합니다. 방법은 다음과 같습니다.
lambda d=d: self.root.change_directory(d)
d를 기본값이 있는 매개 변수로 전달하면 람다 내의 함수가 루프 변수 대신 자체 매개 변수를 참조합니다. 이렇게 하면 각 함수가 디렉터리를 의도한 값으로 변경합니다.
# Another way to bind d: lambda bound_d=d: self.root.change_directory(bound_d)
변경 가능한 개체(예: 목록 및 사전)의 기본값은 공유되므로 이러한 유형을 바인딩할 때는 주의하세요.
추가 클로저 기술
기본 매개변수를 전달하는 것이 이상적이지 않은 경우 다음 대체 클로저를 시도해 보세요. 기법:
중첩 클로저:
(lambda d: lambda: self.root.change_directory(d))(d)
즉시 호출:
(lambda d=d: lambda: self.root.change_directory(d))()
위 내용은 Python 루프의 Lambda 함수가 예기치 않은 동작을 나타내는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!