728x90

블로그 글을 보다 보면 클로저를 익명 함수와 혼동하는 경우가 종종 있다.
아마도 익명 함수를 이요하면서 함수 안에 함수를 정의하는 방식이 보편화 되었기 때문으로 생각된다.
그리고 클로저는 내포된 함수 안에서만 의미가 있다.
따라서 클로저와 익명 함수를 동일한 개념으로 생각하는 사람이 많은 것 같다.

 

class Averager:

    def __init__(self):
        self.series = []

    def __call__(self, new_value):
        self.series.append(new_value)
        total = sum(self.series)
        return total/len(self.series)


avg = Averager()
print(avg(10))
print(avg(11))

10.0과 10.5가 출력된다.

 

밑에서는 클래스가 아닌 함수로 똑같은 기능을 하는 코드를구현 해보겠습니다.

 

def make_averager():
    series = []

    def average(new_value):
        series.append(new_value)
        total = sum(series)
        return total/len(series)

    return average


avg2 = make_averager()
print(avg2(10))
print(avg2(11))

 

위 함수와 클래스로 구현한 객체는 상당히 비슷하다.
Averager() 나 make_averager()를 호출해서 콜러블 객체인 avg가 반환되고
avg는 series를 갱신하고 지금까지의 평균을 계산한다.
avg()는 Averager 클래스의 객체고, avg2는 내부 함수인 average 이다.

 

series 부터 클로저 영역 series.append 에서 series는 자유변수 입니다.

 

지금까지 내용을 정리해보자면 클로저는 함수를 정의할 때 존재하던 자유 변수에 대한 바인딩을 유지하는 함수다.

따라서 함수를 정의하는 범위가 사라진후에 함수를 호출해도 자유 변수에 접근할 수 있다.

함수가 '비전역' 외부 변수를 다루는 경우는 그 함수가 다른 함수 안에 정의된 경우 뿐이라는 점에 주의해야합니다.

 

728x90

'Python > python - pythonic' 카테고리의 다른 글

간단한 데커레이터 구현하기  (0) 2020.11.28
nonlocal 선언 이 필요한 이유  (0) 2020.11.28
변수 범위 규칙  (0) 2020.11.27
데커레이터 함수 이해하기  (0) 2020.11.27
메서드타입 - class method  (0) 2020.11.27