ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] typing
    언어/파이썬 & 장고 2021. 7. 18. 18:29

    python은 동적 타입으로 하나의 변수에 여러 타입의 값을 할당할 수 있습니다. 이는 편하기도 하지만 예상치 못한 버그를 발생시킬 수 있는데 3.5부터 지원하는 typing을 사용하면 ide나 mypy와 같은 라이브러리에서 예상하지 않는 타입을 확인할 수 있습니다. (하지만 typing 모듈을 사용한다고 해서 자바와 같이 컴파일 에러는 발생하지 않습니다.) 3.6 버전 부터는 변수에도 typing을 적용할 수 있는데 아래에서 어떻게 사용하는지 설명합니다.

    여기서는 파이썬 3.8 버전 기준으로 설명을 합니다. 파이썬 3.9에서는 문법이 약간 변경되었는데 이는 아래에서 간략하게 설명을 하겠습니다.

    typing

    변수

    # from typing
    number: int = 1
    name: str = '가나다'

    만약 타입에 맞지 않는 값이 들어온다면 ide(pycharm 기준)에서는 아래와 같이 warning을 띄워줍니다.

    함수

    함수의 파라미터에도 타입을 지정할 수 있고 반환 타입 역시 지정해줄 수 있습니다.

    def temp(number: int) -> bool:
        if number == 1:
            return True

    만약 인자값의 타입이 파라미터 타입과 맞지 않을 경우, warning을 띄워줍니다.

    컨테이너 타입

    list, set, dict와 같은 컨테이너 타입은 아래와 같이 선언하여 사용합니다.

    list

    from typing import List
    
    nums: List[int] = [1, 2, 3, 4, 5]

    set

    from typing import Set
    
    nums: Set[int] = {1, 2, 3, 4, 5}

    dict

    from typing import Dict
    
    nums: Dict[int, str] = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

    불변 타입

    자바의 final과 같이 상수에 대한 타입은 Final을 선언하여 사용합니다.

    from typing import Final
    
    SOLD_OUT: Final[int] = 10

    복수개의 타입

    여러 타입을 허용해야 한다면 Union을 선언하여 사용합니다.

    from typing import Union
    
    def temp(val: Union[int, float]):
        return val
    
    temp(1)
    temp(1.5)

    None을 허용하는 타입

    변수에 None이 들어올 수도 있으면 Optional을 선언하여 사용합니다.

    from typing import Optional
    
    def temp(val: Optional[int]) -> bool:
        if val is None:
            return False
        else:
            return True
    
    temp(1)
    temp(None)

    일급함수 타입

    파이썬은 함수를 변수에 담아 전달하거나 사용할 수 있는데 이 때, Callable을 선언하여 사용할 수 있습니다.

    from typing import Callable
    
    def temp(func: Callable[[str], int], val: str) -> None:
        print(func(val))
    
    def temp2(val: str) -> int:
        return int(val)
    
    temp(temp2, '20')

    Callable의 첫 번째 인자값은 리스트 타입으로 함수의 파라미터 타입들을 받으며 두 번째 인자값은 리턴타입을 선언합니다.

    타입 변환

    새로운 타입을 만들어 이를 검사 할 수도 있습니다.

    from typing import NewType
    
    CustomType = NewType('CustomType', int)
    
    def temp(var: CustomType):
        print(var)
        print(type(var))
    
        # 1
        # <class 'int'>
    
    num = CustomType(1)
    temp(num)

    여기서 int 타입을 전달하면 warning을 볼 수 있습니다.

    제네릭 타입

    자바의 제네릭 타입과 같이 TypeVar를 선언하여 사용할 수 있습니다.

    from typing import TypeVar, List
    
    T = TypeVar('T')
    
    def temp(var: List[T]) -> T:
        return var[0]
    
    temp([1, 2, 3, 4, 5])
    temp(['a', 'b'])

    파이썬 3.9 기준

    파이썬 3.9 버전에서는 사용성이 좀 더 간편해졌습니다. (간편해지면서 삭제된 기능이 엄청 많습니다)

    List, Dict, Set, Iterator, Iterable, Sequence 등등의 대부분 컨테이너 타입이 삭제되었습니다.

    from typing import TypeVar
    
    vars: list[int] = [1, 2, 3, 4]
    vars2: dict[int, str] = {1: 'a', 2: 'b'}
    
    Y = TypeVar('Y')
    dict_type = dict[str, Y][int]
    vars3: dict_type = {'1': 1, '2': 2}

    위와 같이 타입을 선언해서 쓰는 것이 아닌 기존 타입을 사용할 수 있습니다. 또한 함수의 반환 타입을 Iterable로 할지 Sequence로 할지 등등에 대한 고민을 할 필요가 사라졌습니다.

    파이썬 3.9를 기점으로 이전과 사용되는 메소드가 다르니 이를 유의하여 사용하는 것이 좋습니다.

    레퍼런스

    https://docs.python.org/ko/3/library/stdtypes.html#types-genericalias

    https://docs.python.org/ko/3.8/library/typing.html

    댓글