Search

Python Typing

가. Type Hint

1) 기본 자료형

기본 자료형으로 타입 힌트 작성
int_var: int = 11 str_var: str = "hello" float_var: float = 1.123
Python
복사

2) collections

typing 패키지에서 제공 타입 활용
→ 리스트 변수에 대해 list X, List(from typing package)
콜렉션 내 구성요소에 대한 타입 작성 권장
from typing import List, Tuple, Dict list_var: List[str] = ["hello", "world"] tuple_var: Tuple[int] = (1, 2, 3) dict_var: Dict[int, str] = {1: "test"}
Python
복사

나. Type Checking Tool

파이썬 런타임에서 type hint를 무시하므로 type checking tool 활용 필요

1) mypy

대중적으로 널리 사용되는 type checking tool
pip에서 설치 지원

2) pyright

MS에서 개발한 type checking tool
빠른 속도 강점
pip 설치 지원 X

3) 실행

기능 개발에 따른 타입 체킹의 방법으로, 개발된 기능을 독립적인 스크립트 파일로 옮긴 후 스크립트 파일에 대해 타입 체킹을 실행하는 방식이 있음.
mypy 실행 명령: mypy <script file> && python <script file>
→ Pyright의 경우, mypy 대신 pyright 명령

다. Types

1) Callable Type

Callable[[]]: 매개변수로 전달되는 함수에 대한 타입
예시
from typing import Callable def test_callable(func: Callable[[int, int], str]) -> str: return func(1, 2) def print_params(a: int, b: int) -> str: return f'{a}, {b}' print(test_callable(print_params))
Python
복사

2) Class Type

클래스 객체에 대한 타입
클래스 정의부분에 클래스 자체에 대한 타입 선언 시 큰따옴표로 감싸야 한다
→ 큰 따옴료로 감싸지 않으면, 클래스 타입이 정의되지 않은 상태이기 때문에 해당 클래스를 타입으로 사용할 수 없다
→ python 3.10 이상부터는 큰 따옴표가 없어도 동작
예시
from typing import Optional class Human: def __init__(self, a: int, other: Optional["Human"] = None): self.a = a self.other = other def say(self) -> int: return self.a def say_from_other(self) -> int: if self.other is None: return 0 return self.other.say() mj = Human(1) k = Human(2, mj) print(k.say()) print(k.say_from_other())
Python
복사

3) Union Type

하나의 변수에 두 개 이상의 타입을 지정할 수 있도록 정의
예시
from typing import Union class Human: def __init__(self, a: Union[int, str]): self.a = a def say(self) -> Union[int, str]: return self.a def listen_to_human(human: Human) -> Union[int, str]: return human.say() mj = Human(1) jj = Human("hello") print(listen_to_human(mj)) print(listen_to_human(jj))
Python
복사

4) Optional Type

Union Type의 일종으로 None Type을 기본 기본값으로 포함하고 있음
→ Union[str, None] == Optional[str]
→ None Type에 대한 Union Typing을 실무에서 많이 쓰기 때문에 간결한 typing을 위해 제공
예시
from typing import Optional def add_small_int(a: int, b: int) -> Optional[int]: if a > 16 or b > 16: return None return a + b print(add_small_int(5, 6)) print(add_small_int(19, 6))
Python
복사

5) Final Type

속성값을 상수로 지정하여 추후 값 수정을 막는다
→ 파이썬 인터프리터는 공식적으로 상수를 지원하지 않음. 일반적으로 대문자로 쓰는 방식은 파이썬 커뮤니티 안에서의 합의일 뿐임
예시
from typing_extensions import Final FIRST_STATE: Final = "HTTTD" FIRST_STATE = "HHHHH" # error: Cannot assign to final name "FIRST_STATE"
Python
복사

6) Type Alias

타입 별칭을 사용하는 이유: 타입이 복잡하게 정의될 경우, 타입 별칭 사용에 따라 복잡한 타입을 재사용할 수 있음
→ 복잡한 타입에 별칭을 정의함으로서 전체적인 코드가 명확해진다
예시
from typing import Union, Optional, Dict ComplexType = Union[int, str, Optional[Dict[str, float]]] def print_complex_data(a: ComplexType): print(a) print_complex_data("hello") print_complex_data(123)
Python
복사

7) TypedDict

TypedDict 활용할 수 있는 경우: JSON으로 데이터를 주고 받을 때, 키값이 고정된 JSON 객체에 맵핑되는 Dictionary를 정의할 수 있음
TypedDict를 상속 받은 class로 정의
예시
from typing_extensions import TypedDict class SuccessResponse(TypedDict): status: str code: int response: SuccessResponse = {"status": "success", "code": 200} print(response)
Python
복사

8) Generic Type

사용자가 지정한 하나의 타입에 여러 종류의 타입을 동적으로 지정할 수 있음
Generic Type의 경우, 타입 체킹 툴에 따라 다르게 타입을 확인하는 경우가 있으므로 문서를 참고할 필요가 있음
Generic Type의 변수명은 명시성을 위해 대문자 하나로 통칭하는 경우가 많음
예시) Generic with function
from typing import TypeVar, Generic # pyright version # T = TypeVar("T", int, float, str) # H = TypeVar("H", int, float, str) T = TypeVar("T") H = TypeVar("H") def test_generic(x: T) -> T: return x print(f'test_generic: {test_generic(12)}')
Python
복사
예시) Generic with class
from typing import TypeVar, Generic T = TypeVar("T") H = TypeVar("H") class Human(Generic[T, H]): def __init__(self, a: T, b: H): self.a = a self.b = b def say_a(self) -> T: return self.a class Engineer(Generic[T, H], Human[T, H]): def say_b(self) -> H: return self.b mm = Human[int, str](1, "hy") jj = Human[str, int]("hello", 123) mj = Engineer[int, float](9, 3.14) print(f'mm: {mm.say_a()}') print(f'jj: {jj.say_a()}') print(f'mj: {mj.say_b()}')
Python
복사

Reference