it공부 (이야기)

파이썬으로 타입체크 해보자: Type hint 아닙니다. (타입힌트아님)

cantor 2023. 3. 15. 15:12

동기

 

노마드코더의 파이썬 챌린지를 하던 중,

입력받은 숫자를 계산하는 함수를 만들어야 했다.

 

나는 여기서 함수에 인자로 입력받은 숫자에 대한 타입체크를 수행하고 싶었다.

 

파이썬은 함수의 입력인자 및 출력 값의 데이터 타입을 확인하는 기능이 있다.

바로  타입힌트(type hint) 가 그것이다.

 

하지만 이것은 말 그대로 타입 힌트이지 타입체크가 아니다.

아무런 강제성이 없다.

 

 

열받는 출력결과

 

 

 

허접한 영문장으로 구글에 파이썬 유니온타입 타입체크를 검색하자

(how to check union type in python?)

 

스택오버플로우에서는  "typing"이라는 라이브러리를 추천해 주었다.

 

typing 라이브러리 주소
https://docs.python.org/3/library/typing.html

typing.Union
Union type; Union [X, Y] is equivalent to X | Y and means either X or Y.


해당 라이브러리를 통해 타입체크를 구현하는 사람들: 스택오버플로우
https://stackoverflow.com/questions/45957615/check-a-variable-against-union-type-at-runtime-in-python-3-6

 

 

하지만 숫자타입하나 체크하는데 라이브러리까지 데려오고 싶지는 않았다.

 

무엇보다 typing.Union을 사용하더라도 타입체크 기능이 추가되진 않는다.

 

타입힌트는 여전히 타입 힌트다. 

타입가드함수를 따로 만들어주지 않으면 타입 체크기능은 작동하지 않는다.

 

타입체크 불가

 

타입체크 기능을 수행하려면 if문으로 타입가드를 만들어주어야 한다.

주로 isinstance를 이용하길래 나도 그걸 사용하여 타입가드를 만들어보았다.

 

from typing import Union

# type hint에 사용할 Union type 정의

number_type = Union[int, float]

union_type = (int, float)


def multiple_two(x: number_type, y: number_type) -> number_type:

  #타입가드
  if isinstance(x, union_type) and isinstance(y, union_type):
    print(x * y)
  else:
    raise TypeError("input values should be int or float")

multiple_two(5 , 7)

출력결과

 

 

이제 타입체크 기능을 확인하기 위해 "문자"를 넣어서 함수를 실행해 보자.

multiple_two("hello" , 7)

타입체크 성공

 

하지만 여전히 쓸데없기는 마찬가지다.

 

 

반복하지만 typing.Union을 이용하더라도 타입힌트가

강제성을 갖진 않는다.

 

유니온키워드를 쓸 수 있다는 것이 

이 라이브러리의 유일한 의의라면, 대체 왜 사용하는지 모르겠다.

 

 

그런 건 기본 타입힌트로도 가능하다.

유니온 타입힌트

 

그래서 라이브러리 없이 타입체크 함수를 따로 만들어 보았다.

 

"""
타입체크에 쓰일 튜플. 
"""
type_number = (int, float)


def type_check(num1, num2=0):
  """
  함수의 동작내용: 입력받은 값의 타입을 type 함수로 검사한다.
  만약 타입이 type_number 튜플에 들어있지 않다면, TypeError를 발생시킨다.

  두개까지의 입력값에대한 타입검사를 수행하기위해
  default 값 0 을 가진 두번째 파라미터를 추가했다.
  """
    type1 = type(num1)
    type2 = type(num2)
    if (type1 not in type_number) or (type2 not in type_number):
        raise TypeError("input value should be a int or float." + "\n" +
                        f"given types: {type1}, {type2}")

위의 함수를 다른 함수의 시작 부분마다 인자를 넣어 호출하니,

정상적으로 타입체크를 수행할 수 있었다.

 

 

 

 

 

 

 

 

읽어주셔서 감사합니다

오류나 오타가 있으면 댓글에 남겨주세요.

 

 

* 노마드코더 챌린지 정책상 챌린지 과제의 내용은 반출하면 안 됩니다.
하지만 "숫자를 계산하는 함수를 만들었습니다" 정도가 문제가 될 거 같진 않습니다.

문제가 될 시 알려주세요.