English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

파이썬 기본 가이드

파이썬 프로세스 제어

Python 함수

Python 데이터 타입

Python 파일 처리

Python 객체와 클래스

Python 날짜와 시간

Python 고급 지식

Python 참조 매뉴얼

Python 클로저

이 기사에서는 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