본문 바로가기
C++,python (인프런+사이트)/python 파이썬 정리

Class로 구현하는 클로저 기능

by 알 수 없는 사용자 2022. 4. 3.

클로저 설명

# Closure(클로저) 사용 이유
# 서버 프로그래밍 -> 동시성(Concurrency)제어 -> 메모리 공간에 여러 자원이 접근 -> 교착상태(Dead Lock)
# 메모리를 공유하지 않고 메시지 전달로 처리하기 위한 -> Erlang
# 클로저는 공유하되 변경되지 않는(Immutable, Read Only) 적극적으로 사용 -> 함수형 프로그래밍
# 클로저는 불변자료구조 및 atom, STM -> 멀티스레드(Coroutine) 프로그래밍에 강점

한 클래스 or 함수 내에서 shared 데이터 쓰는거 마냥 data를 공유(공통)으로 쓰는 방식

 

말로풀자면 작업 1,2,3,4,5 가 있는데

1작업이 30% 정도 진행되고 있고 2작업이 급하게 해야하는 상황일때, 

1작업을 중단하고 2작업을 끝낸 후, 1의 작업을 마저 한다.  라는 기능이 가능해지는 격

1작업스코프를 벗어났음에도 1작업이 어디까지 했는지 알 수 있기 때문에 이런 기능이 구현됨


Class로 클로저 기능이 구현되는 이유

https://stackoverflow.com/questions/50163080/python-class-closure-is-it-what-it-called

 

Python Class Closure: Is It What It Called?

I know high order functions and closure that is created with function returns. In most of the cases I find it useful and use it repetitively. My question here is related to the closure that is crea...

stackoverflow.com

스택오버플로 답변 : 

바인딩된 메서드라고 합니다.

바인딩된 메서드는 인스턴스(즉 self)와 함수에 대한 참조를 보유하므로 호출될 때 self인수 목록에 삽입됩니다. self물론 다른 모든 멤버 변수에 대한 참조를 보유합니다 

 

내결론 : 클래스를 개체로 생성하면 1.heap메모리 올라간다.  2.__init__때 만들어진 변수는 계속 heap에 남아있다. 3.class에 인자로 data를 넘길 때 __call__일급함수로 넘긴다. 

1,2,3 같이 하면 __call__에서 data를 넘겨 받고 __init__에 있는 변수는 계속 누적이 된다. -> 따라서 클래쓰를 클로저처럼 쓴다 라는 말인듯

 

다른데 글 보면 class로 구현하는게 가독성도 좋고 더좋은거 같은데 왜 closure기능을 쓰냐 라는 질문이 있는데

거기서 답변은 속도차이가 난다고함.

python 2에서는 2배, python 3 에서는 1.5 배정도 차이가 났다고함 (closure쪽 우세)

따라서 변수가 적으면 closure함수를, 변수가 많을 시엔 Class를 이용하는 것이 유리함


코드설명 ( class로 클로저 구현 )

Class Averager를 선언하고 __call__매직함수로 Class를 함수처럼 불러올 수 있게 만든다.

__call__함수를 클로저 함수형식으로 코딩한다.

# Closure(클로저) 사용 이유
# 서버 프로그래밍 -> 동시성(Concurrency)제어 -> 메모리 공간에 여러 자원이 접근 -> 교착상태(Dead Lock)
# 메모리를 공유하지 않고 메시지 전달로 처리하기 위한 -> Erlang
# 클로저는 공유하되 변경되지 않는(Immutable, Read Only) 적극적으로 사용 -> 함수형 프로그래밍
# 클로저는 불변자료구조 및 atom, STM -> 멀티스레드(Coroutine) 프로그래밍에 강점

# 클래스 이용
class Averager():
    def __init__(self):
        self._series = []

    def __call__(self, v):
        self._series.append(v)
        print('inner >>> {} / {}'.format(self._series, len(self._series)))
        return sum(self._series) / len(self._series)


def test(v):
    _series = []
    _series.append(v)
    print('inner >>> {} / {}'.format(_series, len(_series)))
    return sum(_series) / len(_series)


# 인스턴스 생성
averager_cls = Averager()

# 클로저 누적
print(averager_cls(10))
print(averager_cls(20))
print(averager_cls(30))

# 일반함수 누적X
print(test(10))
print(test(20))
print(test(30))
print()
print()

콘솔 결과창

밑에 3개는 클로저기능구현안된거

 

댓글