본문 바로가기
Python/기본문법

파이썬 Type Hint (타입 정보 명시적 표시)

by yororing 2024. 5. 8.

00 개요

  • 파이썬을 사용하고 있는 도중에 강사가 todos:  List[ToDo] = get_todos(session=session)와 같이 '타입 힌트'라는 것을 사용하는데 뭔지 몰라서 알아보고자 함

01 Type Hint란

0. 예시

# typing 모듈 사용 시
from typing import List, Set, Dict, Tuple, Optional

nums: List[int] = [1, 2, 3]
unique_nums: Set[int] = {1, 2, 3}
vision: Dict[str, float] = {"left"L 1.0, "right": 0.9}
jhon: Tuple[int, str, List[float]] = (25, "John Doe", [1.0, 0.9])
grades: Optional[int] = None
# 함수 내에서 사용 시
def stringify(num: int) -> str:
    return str(num)

def plus(num1: int, num2: float = 3.5) -> float:
    return num1 + num2

def greet(name: str) -> None:
    print("Hi! " + name)

def repeat(message: str, times: int = 2) -> list:  # 파이썬 3.8 이하
    return [message] * times

def repeat(message: str, times: int = 2) -> list[str]:  # 파이썬 3.9 이상
    return [message] * times
    
def foo(arg: Optional[int] = None) -> None:

1. 정의

  • type hinting 또는 type annotation
  • 파이썬 3.5 버전부터 추가된 기능
  • 코드에 타입 정보를 명시적으로 표시하는 방법
  • 함수에 type hinting 적용 시 인자 타입과 반환 타입에 추가 가능
    • 인자에 type hinting을 추가 시 변수와 동일한 문법 사용, 콜론(:)으로 표현
    • 반환값에 추가 시 화살표(->)로 표현
  • 자바스크립트의 확장인 타입 스크립트와 비슷한 느낌
  • 코드에 대한 메타 정보로서 코드의 가독성과 안정성을 높임
  • 파이썬 문법에 포함되어 있으나 실제로 코드의 실행에는 영향을 주지 않음
    • →타입 힌트가 잘못되어 있어도 파이썬 인터프리터는 그것을 무시하고 코드 실행함

1) 설명

  • 파이썬은 동적 타이핑 (dynamic typing) 언어로서 변수의 타입이 실행 시점에 결정되고 후에 변경 가능
  • 예를 들어 다음 코드는 파이썬에서 문제없이 실행됨
num = 1 # int 타입
num = "1" # str 타입
  • 그러나 이런 유연함으로 인해 버그 발생 가능
  • 다음 함수는 인자로 정수를 받아 두 배를 반환하는 함수
def double(num):
    return num * 2

>>> double(3)	# 정상 작동
6
>>> double("3")	# 원하는 결과값 아님
'33'
  • 위와 같이 정수를 인자로 주면 잘 작동하지만 문자열을 인자로 넘겨주면 예상과 다른 결과를 반환
  • 이런 경우 타입 힌트 사용하여 함수의 인자와 반환값에 타입을 명시할 수 있음
def double(num: int) -> int:
    return num * 2
  • def double(num: int) -> int:
    • num: int → num이라는 인자를 받는데 이 인자의 타입은 int로 명시
    • - > int → 반환값의 타입을 int로 명시
  • 이렇게 하면 코드를 읽는 사람이나 개발 도구가 함수의 의도를 더 잘 파악 가능
  • 예를 들어 코드 편집기에서는 타입 힌트를 통해 자동 완성이나 타입 검사를 제공할 수 있음

02 Type Hint 종류

# Super-special typing primitives.
'Annotated',
'Any',
'Callable',
'ClassVar',
'Concatenate',
'Final',
'ForwardRef',
'Generic',
'Literal',
'Optional',
'ParamSpec',
'Protocol',
'Tuple',
'Type',
'TypeVar',
'TypeVarTuple',
'Union'

# ABCs (from collections.abc).
'AbstractSet',  # collections.abc.Set.
'ByteString',
'Container',
'ContextManager',
'Hashable',
'ItemsView',
'Iterable',
'Iterator',
'KeysView',
'Mapping',
'MappingView',
'MutableMapping',
'MutableSequence',
'MutableSet',
'Sequence',
'Sized',
'ValuesView',
'Awaitable',
'AsyncIterator',
'AsyncIterable',
'Coroutine',
'Collection',
'AsyncGenerator',
'AsyncContextManager'

# Structural checks, a.k.a. protocols.
'Reversible',
'SupportsAbs',
'SupportsBytes',
'SupportsComplex',
'SupportsFloat',
'SupportsIndex',
'SupportsInt',
'SupportsRound',

# Concrete collection types.
'ChainMap',
'Counter',
'Deque',
'Dict',
'DefaultDict',
'List',
'OrderedDict',
'Set',
'FrozenSet',
'NamedTuple',  # Not really a type.
'TypedDict',  # Not really a type.
'Generator'

# Other concrete types.
'BinaryIO',
'IO',
'Match',
'Pattern',
'TextIO'

# One-off things.
'AnyStr',
'assert_type',
'assert_never',
'cast',
'clear_overloads',
'dataclass_transform',
'final',
'get_args',
'get_origin',
'get_overloads',
'get_type_hints',
'is_typeddict',
'LiteralString',
'Never',
'NewType',
'no_type_check',
'no_type_check_decorator',
'NoReturn',
'NotRequired',
'overload',
'override',
'ParamSpecArgs',
'ParamSpecKwargs',
'Required',
'reveal_type',
'runtime_checkable',
'Self',
'Text',
'TYPE_CHECKING',
'TypeAlias',
'TypeGuard',
'TypeAliasType',
'Unpack'

1. Special Forms

  • typing.Union
    • Union[X, Y]은 X | Y 와 동일
    • either X or Y임을 명시
# 가능한 형태
Union[Union[int, str], float] == Union[int, str, float]
Union[int] == int
Union[int, str, int] == Union[int, str] == int | str
Union[int, str] == Union[str, int]

# 다음은 안 됨
Union[X][Y]
  • typing.Optional
    • Optional[X]은 X | None (or Union[X, None]) 와 동일
    • 즉, Optional[int]는 값이 int 또는 None임을 명시

03 Type Annotation 검사

  • 코드에 추가한 타입 어노테이션을 검사하고 싶을 때 __annotations__ 내장 사전 객체 사용 가능
>>> __annotations__
{'no': <class 'int'>, 'name': <class 'str'>, 'age': <class 'int'>, 'address': <class 'dict'>}

# repeat 함수가 아래와 같을 때

# 파이썬 3.8 이하
def repeat(message: str, times: int = 2) -> list:
    return [message] * times

# 파이썬 3.9 이상
def repeat(message: str, times: int = 2) -> list[str]:
    return [message] * times

# repeat의 type annotations
>>> repeat.__annotations__
{'message': <class 'str'>, 'times': <class 'int'>, 'return': <class 'list'>}

 

참조

  1. https://www.daleseo.com/python-type-annotations/#google_vignette 
  2. https://dahanda-w.com/파이썬-타입-힌트란-타입-힌트의-모든것/#:~:text=파이썬%20타입%20힌트는%20파이썬,지원을%20받을%20수%20있습니다.
  3. https://docs.python.org/3/library/typing.html
  4. (typing 소스 코드) https://github.com/python/cpython/blob/3.12/Lib/typing.py
  5.  
  6.  

'Python > 기본문법' 카테고리의 다른 글

sys (인터프리터 제어 모듈)  (0) 2024.06.13
re (정규표현식 작업 모듈)  (0) 2024.06.13
Generator (제너레이터)  (0) 2024.05.03
dict.pop() 메소드  (0) 2024.04.17
os.path vs pathlib.Path (파일 경로 다루기)  (0) 2024.03.27