[Python] Skill of coding - 키워드 전용 인수로 명료성을 강요

Hyeseong·2020년 12월 10일
0

python skill of coding

목록 보기
14/18

키워드 전용 인수로 명료성을 강요하기

키워드로 인수를 넘기는 방법은 파이썬 함수의 강력한 기능이에요.
키워드 인수의 유연성 덕분에 쓰임새가 분명하게 코드를 작성 할 수 있어요.

예. 어떤 숫자를 다른 숫자로 나눈다고 하자. 이 경우 특별한 경우에 주의해야 한다. 때로는 ZeroDivisionError 예외를 무시하고 무한대 값을 반환하고 싶을 수 있다. 어떨 때는 OverflowError 예외를 무시하고 0을 반환하고 싶을 수 있다.

def safe_division(number, divisor, ignore_overflow,
                  ignore_zero_division):
    try:
        return number / divisor
    except OverflowError:
        if ignore_overflow:
            return 0
        else:
            raise
    except ZeroDivisionError:

이 함수를 사용하는 방법은 심플하다. 다음 한수 호출은 나눗셈에서 일어나는 float 오버플로우를 무시하고 0을 반환한다.


result = safe_division(1.0, 10**500, True, False)
print(result)
assert result is 0
0

다음 함수 호출은 0으로 나누면서 일어나는 오류를 무시하고 무한대 값을 반환한다.


result = safe_division(1,0,False, True)
print(result)
inf

문제는 예외 무시 동작을 제어하는 두 불 인수의 위치를 혼동하기 쉽다는 점이다. 이 때문에 찾기 어려운 버그가 쉬이 발생할 수 있다. 이런 코드의 가능성을 높이는 한 가지 방법은 키워드 인수를 사용하는 것이다. 다음과 같이 함수가 기본적으로 매우 주의 깊고 항상 예외를 다시 일으키게 만들 수 있다.


    except ZeroDivisionError:
        if ignore_zero_division:
            return float('inf')
        else:
            raise

그러면 호출하는 쪽에서 키워드 인수로 특정 연산에는 기본 동작을 덮어쓰고 무시할 플래그를 지정할 수 있다.

assert safe_division_b(1.0, 10**500, ignore_overflow=True) is 0
assert safe_division_b(1.0, 0, ignore_zero_division=True) == float('inf')

문제는 이런 키워드 인수가 선택적인 동작이라서 함수를 호출하는 쪽에 키워드 인수로 의도를 명확하게 드러내라고 강요할 방법이 없다는 점이다. safe_division_b라는 새 함수를 정의한다고 해도 여전히 위치 인수를 사용하는 이전 방식으로 호출할 수 있다.

safe_division(1, 10**500, True, False)
0.0

이처럼 복잡한 함수를 작성할 때는 호출하는 쪽에서 의도를 명확히 드러내도록 요구하는 게 낫다. 키워드 전용 인수로 함수를 정의해서 의도를 명확히 드러내도록 요구할 수 있다. 키워드 전용 인수는 키워드로만 넘길 뿐, 위치로는 절대 넘길 수 없다.

다음은 키워드 전용 인수로 safe_division 함수를 다시 정의한 버전이다. 인수 리스트에 있는 * 기호는 위치 인수의 끝과 키워드 전용 인수의 시작을 가리킨다.

def safe_division_c(number, divisor, * , ignore_overflow=False, ignore_zero_division=False):
    pass

이제 키워드 인수가 아닌 위치 인수를 사용하는 함수 호출은 동작 하지 않는다.

safe_division_c(1, 10**500, True, False)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-162-2f9b657427b5> in <module>
----> 1 safe_division_c(1, 10**500, True, False)

TypeError: safe_division_c() takes 2 positional arguments but 4 were given

키워드 인수와 그 기본값은 기대한 대로 동작한다.

safe_division_c(1.0, 0, ignore_zero_division=True)  # No exception
try:
    safe_division_c(1.0, 0)
except ZeroDivisionError:
    pass  # Expected

핵심정리

  • 키워드 인수는 함수 호출의 의도를 더 명확하게 해준다
  • 특히 불 플래그를 여러 개 받는 함수처럼 헷갈리기 쉬운 함수를 호출할 때 키워드 인수를 넘기게 하려면 키워드 전용 인수를 사용하자.
  • 함수의 키워드 전용 인수 문법을 명시적으로 지원함.
profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글