TIL 231225 - Python 장식자로 정책과 메커니즘을 나눈다?

김장군·2023년 12월 25일
0

TIL

목록 보기
3/3

눈물의 1225 TIL... 그래도 배운 게 있으면 됐다 ㅋㅋㅋ

DB를 쓰는 코드를 짤 때, 에러를 생각해야 한다.
DB는 멈출 수도 있고 네트워크가 끊길 수도 있고 인풋 데이터 사이 충돌이 생길 수도 있고 별 에러가 나타날 수 있다.
이러한 코드를 돌릴 때 에러가 있을 수 없다고 생각하는 것은 그냥 생각이 짧고 경험이 없다는 것을 보여 주는 것이다.
비즈니스 코드를 짤 때는 에러가 난다고 해서 프로세스가 멈추면 안 된다.
몇 번의 retry 로직이 있어야 한다.

그러나 좀 더 생각해 보자.
그렇다면 DB를 쓰는 함수마다 로직을 짜는 것은 말이 안 된다.
Python의 backoff 라이브러리를 써 보자.
이 라이브러리는 retry 로직을 쉽게 정의할 수 있게 하고, temp 에러를 프로세싱하기 쉽게 만들어 준다.

이런 식으로 정책과 메커니즘을 나누는 것은 아주 중요하다.
정책: 무엇을 할 것인가.
메커니즘: '어떻게' 할 것인가.
정책은 환경에 따라 아주 쉽게 바뀔 수 있기 때문에,
정책과 메커니즘을 나누지 않았다면 정책이 바뀔 때마다 더 많은 코드를 지우고 써야 한다.

하나의 함수 안에 정책과 메커니즘이 모두 들어 있지 않게 해 보자.
하나의 정책은 하나의 함수에.
하나의 메커니즘은 하나의 함수에.

함수는 짧을수록 한 눈에 이 함수가 무슨 일을 하는지 알기가 쉬워진다는 것을 잊지 말자.


이 밖에도 많은 라이브러리들이 어떠한 메커니즘을 장식자로 이쁘게 만들어 두었을 것이다.

장식자를 적극적으로 찾고 써 보자.

예를 들면...

  • 함수의 아웃풋을 캐시에 담아 두는 functools.lru_cache: 함수의 인수와 그 아웃풋은 dict에 쌓이게 된다. 따라서 이 장식자를 쓰는 함수의 인수는 넘버, strings, tuples처럼 dict's key로 쓰일 수 있어야 한다. 아래 my_fibo 함수에서 캐시를 쓸 때와 안 쓸 때 시간이 많이 다를 것이다.
# https://kimjingo.tistory.com/169

from time import time
from functools import lru_cache


@lru_cache(maxsize=32)
def my_fibo(n):
    if n == 0:
        return 0
    elif n == 1 or n == 2:
        return 1
    else:
        return my_fibo(n - 1) + my_fibo(n - 2)

start_time = time()
output = my_fibo(40)
end_time = time() - start_time
print(output, end_time)
  • 다음으로, CLI를 더 쉽게 만들어 주는 Click 라이브러리가 있다. 여기를 봐 보자.
  • 함수에게 시간 리밋을 줄 수 있는 timeout_decorator 라이브러리도 잘 쓰면 아주 좋겠다.
profile
Make impacts!

0개의 댓글