English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
이 기사에서는 Python 클로저가 무엇인지, 어떻게 정의할 수 있는지, 그리고 클로저를 사용하는 이유를 이해할 것입니다.
클로저가 무엇인지 이해하기 전에, 먼저 내장 함수와 비지역 변수가 무엇인지 이해해야 합니다.
또 다른 함수 내에서 정의된 함수는 내장 함수라고 합니다. 내장 함수는 닫힌 범위의 변수에 접근할 수 있습니다.
Python에서는 기본적으로 이러한 비지역 변수는 읽기 전용이며, 우리는 명시적으로 비지역 변수로 선언해야 합니다 (nonlocal 키워드를 통해 수정할 수 있습니다。
비지역 변수에 접근하는 내장 함수의 예제입니다
def print_msg(msg): # 이는 외부 닫힌 함수입니다 def printer(): # 이는 내장 함수입니다 print(msg) printer() # 이 함수를 실행합니다 # 출력: Hello print_msg("Hello")
嵌套 함수printer()가 닫힌 함수의 비지역 변수에 접근할 수 있다는 것을 볼 수 있습니다msg。
위의 예제에서 print_msg() 함수의 마지막 행이 printer() 함수를 호출하지 않고 반환하면 어떻게 될까요? 이는 다음과 같은 기능 정의를 의미합니다.
def print_msg(msg): # 이는 외부 닫힌 함수입니다 def printer(): # 이는 내장 함수입니다 print(msg) return printer # 이는 바뀌었습니다 # 이제, 이 함수를 호출해 보겠습니다. # 출력: Hello another = print_msg("Hello") another()
이는 매우 이상합니다.
print_msg() 함수는 문자열로 호출되어, "Hello"이 반환하는 함수가 바인딩됩니다다른이름. another()를 호출할 때, print_msg() 함수 실행이 완료되었음에도 불구하고 여전히 이 메시지를 기억합니다.
일부 데이터("Hello")를 코드에 추가하는 기술Python에서이라고 합니다클로저。
변수가 범위를 벗어났거나 함수 자체가 현재 이름 공간에서 제거되었어도, 닫힌 범위에서 이 값을 기억합니다.
Python Shell에서 다음 명령어를 실행하여 출력을 확인하세요。
>>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (최근 호출이 마지막): ... 이름 오류: 이름 'print_msg'가 정의되지 않았습니다
위의 예제에서 보면, 파이썬에서 내부 함수가 닫힌 범위에서 값을 참조할 때, 우리는 클로저를 가지고 있습니다.
이 점들은 파이썬에서 클로저를 생성하기 위해 만족해야 할 조건을 요약합니다.
우리는 내부 함수(함수 내에 함수)를 가져야 합니다.
내부 함수는 닫힌 함수에서 정의된 값을 참조해야 합니다.
닫힌 함수는 내부 함수를 반환해야 합니다.
클로저는 무엇을 위한 것인가요?
클로저는 전역 값을 사용하지 않고 데이터 숨기기를 제공하며, 이 문제에 대한 대상적인 해결책을 제공할 수 있습니다.
클래스에서 구현할 메서드가 적을 때(대부분의 경우 하나의 메서드만 있습니다) 클로저는 더 우아한 해결책을 제공할 수 있습니다. 그러나 속성과 메서드의 수가 많아지면 최선의 방법은 클래스를 구현하는 것입니다.
이는 클로저가 클래스 정의와 객체 생성보다 더 적합할 수 있는 간단한 예제입니다.
def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # 3의 배수 times3 = make_multiplier_of(3) # 5의 배수 times5 = make_multiplier_of(5) # 출력: 27 print(times3(9)) # 출력: 15 print(times5(3)) # 출력: 30 print(times5(times3(2))
파이썬의 데코레이터도클로저를 많이 사용했습니다.
마지막으로, 닫힌 함수 안에 닫힌 함수에 닫힌 값을 찾을 수 있다는 점을 강조합니다.
모든 함수 객체는 __closure__ 속성을 가지며, 클로저 함수라면 이 속성은 셀 객체의 튜플을 반환합니다. 위의 예제에서 times3과 times5은 클로저 함수입니다.
>>> make_multiplier_of.__closure__ >>> times3.__closure__ (<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)
셀 객체는 저장된 닫힌 값을 가진 속성 cell_contents를 가집니다.
>>> times3.__closure__[0].cell_contents 3 >>> times5.__closure__[0].cell_contents 5