중첩 함수는 더 넓은 컨텍스트 내에서 코드를 구성하고 기능을 캡슐화하는 편리한 방법을 제공합니다. 그러나 중첩된 범위 내에서 변수가 처리되는 방식을 이해하면 개발자가 당황할 수 있습니다.
다음 코드 조각을 고려하세요.
class Cage(object): def __init__(self, animal): self.animal = animal def get_petters(): for animal in ['cow', 'dog', 'cat']: cage = Cage(animal) def pet_function(): print("Mary pets the " + cage.animal + ".") yield (animal, cage.animal)
이 예에서 생성기 함수 get_petters()는 동물 목록, 각각에 대한 Cage 객체를 생성하고 동물의 이름과 케이지 로컬에 액세스하려고 시도하는 중첩 함수를 포함하는 튜플을 생성합니다. 변수.
이 코드를 실행하면 케이지 변수의 세 가지 다른 인스턴스에 해당하는 세 가지 다른 동물이 인쇄되는 것을 볼 수 있습니다. 그러나 출력에는 "Mary pet the cat"만 반복적으로 생성됩니다.
문제의 핵심은 Python의 클로저 특성에 있습니다. 중첩된 함수가 정의되면 해당 함수는 바깥쪽 범위에 있는 변수에 대한 참조를 캡처합니다. 제공된 코드에서 pet_function은 get_petters() 함수 내에 중첩되어 있으므로 케이지 변수에 액세스할 수 있습니다.
그러나 이 참조는 함수 정의 시 설정되지 않습니다. 대신 함수 실행 시 발생합니다. 중첩된 함수가 실행될 때쯤에는 동물 목록을 반복하면서 케이지 변수에 이미 'cat' 값이 할당되었습니다.
이 문제를 해결하려면 다음을 수행할 수 있습니다. 여러 가지 접근 방식을 채택합니다.
1. 부분 함수:
부분 함수는 기존 함수를 래핑하고 해당 인수 중 일부를 미리 설정된 값으로 초기화하는 호출 가능 항목입니다. 이 경우 functools.partial()을 사용하여 케이지 변수를 적절한 컨텍스트에 바인딩하는 부분 pet 함수를 생성할 수 있습니다:
def pet_function(cage=None): print("Mary pets the " + cage.animal + ".") yield (animal, partial(pet_function, cage=cage))
2. 새 범위 만들기:
또 다른 옵션은 케이지 변수가 항상 로컬에서 올바른 값에 바인딩되도록 중첩된 범위 내에서 pet 함수를 정의하는 것입니다.
def scoped_cage(cage=None): def pet_function(): print("Mary pets the " + cage.animal + ".") return pet_function yield (animal, partial(pet_function, cage))
3. 기본 키워드 매개변수:
cage 변수를 pet 함수의 기본 키워드 인수로 전달할 수도 있습니다.
def pet_function(cage=cage): print("Mary pets the " + cage.animal + ".") yield (animal, partial(pet_function))
이러한 기술을 준수하면 중첩된 함수는 예상되는 지역 변수와 함께 작동하여 예상치 못한 부작용을 제거하고 코드 명확성을 유지합니다.
위 내용은 Python의 중첩 함수가 루프 변수의 마지막 값에만 액세스하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!