안전성 있는 curry? 좀 더 쓰기 편한 curry
def curry(func) :
curry.__func_name__ = func.__name__
f_args, f_kwargs = [], {}
def f(*args, **kwargs) :
nonlocal f_args, f_kwargs
if args or kwargs :
print("args", args, "kwargs", kwargs)
f_args += args
f_kwargs.update(kwargs)
if len(f_args) + len(f_kwargs) >= func.__code__.co_argcount :
result = func( *f_args, **f_kwargs)
f_args, f_kwargs = [], {}
return result
return f
else :
print( f_args, f_kwargs)
result = func( *f_args, **f_kwargs)
f_args, f_kwargs = [], {}
return result
return f
위는 이전에 작성했던 curry 문 이다. 물론 이 curry문도 curry로서 잘 동작하지만 한 가지 문제점이 있다. 바로
def curry(func) :
curry.__func_name__ = func.__name__
f_args, f_kwargs = [], {} <------------ 변수 설정 및 저장..
처음에 변수를 미리 선언하고 값이 들어올때 마다 추가시키기 때문에 아래 처럼 curry를 decorator로 add 함수를 부르게 되면 (decorator는 추후에 한번 다루기로 하겠다)
@curry
def add( x, y ) :
return x + y
print(add(1))
print(add(2))
'''
args (1,) kwargs {}
<function curry.<locals>.f at 0x0000020C57BF8558>
args (2,) kwargs {}
3
'''
위 처럼 add(1)에서 1를 가지고 있다가 add(2)를 한번 더 호출했을 때 두 변수의 합이 산출되는 것을 확인 할 수 있다.
위 처럼 사용하면 물론 장점도 있지만, 함수가 계속 변수를 저장하고 있다는 점에서 같은 함수를 다시 재사용하고 싶을 때 현재 그 함수가 저장된 변수가 있는지 없는지 확인해야 하는 번거로움을 가지게 된다.
좀 더 직관적으로 쓰기 편한 curry
따라서 알고리즘을 좀 더 쉽게 풀기 위해서 변수를 저장하지 않는 형식으로 add(1)(2) 라고 바로 호출할때 만 사용 되는 curry 문을 만들어 보자
def curry(func) :
curry.__func_name__ = func.__name__
# f_args, f_kwargs = [], {} <---- 단순하다 변수를 선언해준 부분만 주석처리
def curried(*args, **kwargs) :
def f(*args2, **kwargs2) :
nonlocal args, kwargs
args += args2
kwargs.update(kwargs2)
return curried(*args, **kwargs)
if len(args) + len(kwargs) >= func.__code__.co_argcount :
return func( *args, **kwargs)
else :
return f
return curried
새롭게 작성한 curry 문이다. 보면 그렇게 크게 변한것이 없어 보인다. 위에 변수를 선언한 부분을 빼면 그렇게 크게 변한것이 없어보인다. 실제로 사용해보면서 확인해보자
@curry
def add( x, y ) :
return x + y
print(add(1))
print(add(2))
'''
<function curry.<locals>.curried.<locals>.f at 0x0000020C549E9318>
<function curry.<locals>.curried.<locals>.f at 0x0000020C57CE6168>
'''
똑같이 add 함수를 적용하여 add(1), add(2)를 각각 출력 시켜 보았다. 출력을 보면 각각 별개의 주소를 가진 함수를 출력하는 것을 확인 할 수 있다. 우리는 이로서 같은 함수 이름이지만 독립적인 curry 함수를 만들어 사용할 수 있게 되었다. 물론 위 처럼 쓰는 방식이 마냥 좋은 것은 아니지만 앞으로 알고리즘을 문제를 풀 때 조금 더 편하게 사용할 수 있다는 장점을 가지고 있다.
'함수형 프로그래밍 > python' 카테고리의 다른 글
일반적인 숨바꼭질 문제 (0) | 2021.07.22 |
---|---|
curry, reduce를 사용하여 함수 열거형 go 만들기 (0) | 2021.07.20 |
reduce, 원하는 함수로 배열 혹은 값을 누적처리하여 결과값을 구해보자 (0) | 2021.07.17 |
python curry update (0) | 2021.07.16 |
python 으로 curry 만들기 (0) | 2021.07.15 |
댓글