> 백엔드 개발 > 파이썬 튜토리얼 > 중첩된 Python 함수가 정의 시간이 아닌 실행 시간에 변수에 액세스하는 이유는 무엇입니까?

중첩된 Python 함수가 정의 시간이 아닌 실행 시간에 변수에 액세스하는 이유는 무엇입니까?

Patricia Arquette
풀어 주다: 2024-12-24 13:27:30
원래의
884명이 탐색했습니다.

Why Do Nested Python Functions Access Variables at Execution Time, Not Definition Time?

중첩 함수 및 지역 변수 액세스

Python에서 중첩 함수는 바깥쪽 범위에서 지역 변수에 액세스할 수 있습니다. 그러나 이 액세스 시점은 직관에 어긋날 수 있습니다.

다음 코드 조각을 고려하세요.

class Cage(object):
    def __init__(self, animal):
        self.animal = animal

def gotimes(do_the_petting):
    do_the_petting()

def get_petters():
    for animal in ['cow', 'dog', 'cat']:
        cage = Cage(animal)

        def pet_function():
            print "Mary pets the " + cage.animal + "."

        yield (animal, partial(gotimes, pet_function))

funs = list(get_petters())

for name, f in funs:
    print name + ":",
    f()
로그인 후 복사

Mary가 각 동물을 애완동물로 키우는 예상 출력을 얻는 대신 출력에는 "Mary 애완동물을 애완동물로 키우는 사람"이 표시됩니다. 고양이"는 세 동물 모두에 해당됩니다. 이러한 현상은 중첩된 함수 pet_function이 정의 시점이 아닌 실행 시점에 지역 변수 케이지를 조회하기 때문에 발생합니다.

get_petters 함수가 호출되면 지역 변수 케이지가 각 동물에 순차적으로 할당됩니다. 루프 내에서. 그러나 함수가 끝나면 케이지에는 마지막 값('cat')이 포함됩니다. get_petters에서 반환된 함수가 호출되면 모두 'cat' 값을 사용하여 동일한 케이지 변수에 액세스합니다.

이 문제를 해결하려면 다음과 같은 다양한 기술을 사용할 수 있습니다.

  • 바운드 케이지에 부분 함수 사용 변수:

    from functools import partial
    
    def pet_function(cage):
      print "Mary pets the " + cage.animal + "."
    
    yield (animal, partial(gotimes, partial(pet_function, cage=cage)))
    로그인 후 복사
  • 중첩 함수에 대한 새 범위 만들기:

    def scoped_cage(cage):
      def pet_function():
          print "Mary pets the " + cage.animal + "."
      return pet_function
    
    yield (animal, partial(gotimes, scoped_cage(cage)))
    로그인 후 복사
  • 변수를 키워드 매개변수:

    def pet_function(cage=cage):
      print "Mary pets the " + cage.animal + "."
    
    yield (animal, partial(gotimes, pet_function))
    로그인 후 복사

위 내용은 중첩된 Python 함수가 정의 시간이 아닌 실행 시간에 변수에 액세스하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿