if/else 대신 dict로 get() 함수 사용하기

Jihun Kim·2022년 3월 28일
0

Django

목록 보기
8/8
post-thumbnail

아래 내용은 업무 중 코드 리뷰 받은 내용이 많은 도움이 되어 정리한 것입니다.


if/else문을 사용한 다음과 같은 코드를 살펴보자.

[if/else문을 사용한 코드]

def get_period(period: PeriodTypeChoices.choices):
    if period == PeriodTypeChoices.weekly:
        return self._get_start_and_end_date_weekly()
    elif period == PeriodTypeChoices.monthly:
        return self._get_start_and_end_date_monthly()
    elif period == PeriodTypeChoices.yearly:
        return self._get_start_and_end_date_yearly()
    else:
        raise PeriodException(해당하는_날짜가_존재하지_않습니다)

만약 if/else문이 10개 이상으로 늘어나게 된다면 그 때는 협업을 하는 입장에서 해당 코드를 다 읽어보기가 어려울 것이다.
이럴 때 사용할 수 있는 방법이 해당 if/else문을 아래와 같이 dictionary에 정의하는 것이다.

[dictionary를 사용한 코드]

def get_period(self, period: PeriodTypeChoices.choices):
    periods = {
        PeriodTypeChoices.weekly: self._get_start_and_end_date_weekly,
        PeriodTypeChoices.monthly: self._get_start_and_end_date_monthly,
        PeriodTypeChoices.yearly: self._get_start_and_end_date_yearly,
    }
    return periods.get(period, None)

아래에서 dictionary를 사용할 때의 장점을 살펴 보자.



가독성을 높일 수 있다

if/else문을 사용한 코드와 dictionary를 사용한 코드를 비교해 보면 한 눈에 보기에 dictionary를 사용한 코드가 가독성이 더 높다는 것을 알 수 있다. 협업에는 가독성이 매우 중요한 사항이기 때문에 무시할 수 없는 요소이다.


if 또는 else에 해당하는 내용을 추가하기가 쉽다

if/else문을 사용할 경우 if문, else, 그리고 return까지 추가해 해당하는 구문을 만들어야 한다. 그러나 dictionary를 사용하는 경우 해당 key/value만 추가하면 되기 때문에 코드 확장성이 높다.


버그를 쉽게 잡을 수 있다

만약 if문에 걸렸으나 해당 if문에서 또 다시 분기를 했어야 했지만 놓쳤을 경우 에러를 잡을 수 없게 된다. 하지만 key/value로 값을 추가해 놓는다면 해당 key가 없을 경우 바로 버그를 잡을 수 있어 버그를 쉽게 잡을 수 있다는 것이다.

이 때 <dict>.get(value, dafult)을 이용하면 default value도 정의할 수 있기 때문에 if/else문에서 else 없이 elif로만 끝나는 코드에서 발생할 수 있는 에러를 잡을 수 있다. 이 때, default value가 Exception을 raise하기를 원할 경우 아래와 같은 코드를 생성할 수 있다.

먼저, lambda 함수 내에서 Exception을 raise하기 위한 함수를 정의한다.

def raise_(ex):
    raise ex

그리고 아래와 같이 해당하는 key 값이 없을 경우 default로 Exception을 raise하도록 정의할 수 있다.

def get_period(self, period: PeriodTypeChoices.choices):
    periods = {
        PeriodTypeChoices.weekly: self._get_start_and_end_date_weekly,
        PeriodTypeChoices.monthly: self._get_start_and_end_date_monthly,
        PeriodTypeChoices.yearly: self._get_start_and_end_date_yearly,
    }
    return periods.get(
    	period, 
        lambda: raise_(PeriodException(해당하는_날짜가_존재하지_않습니다))()

key/value에 대한 type hint를 추가할 수도 있다

아래와 같은 방법으로 type hint를 추가해서 key/value를 추가할 때 dictionary를 업데이트 하도록 만들 수도 있을 것이다.

def get_info(period: PeriodTypeChoices.choices, func: Callable[[], (str, str)]) -> Dict[PeriodTypeChoices.choices, Callable[[], (str, str)]]:
    periods.update({period: func})
    return periods


정리하면 다음과 같다.
1. 가독성을 높일 수 있다.
2. if/else문을 추가하기 쉽다.
3. 버그를 쉽게 잡을 수 있다.
4. key에 대한 type hint를 추가할 수 있다.



여기에도 잘 정리되어 있다. 추가로 참고하면 좋을 것 같다.

profile
쿄쿄

0개의 댓글