본문 바로가기
Python

[Python] 타입 어노테이션/힌트

by xangmin 2022. 4. 11.
반응형

파이썬 동적 프로그래밍 언어

동적(dynamic) 프로그래밍 언어인 파이썬에서는 인터프리터(interpreter)가 코드를 실행하면서 타입(type)을 추론하여 체크한다. 또한 파이썬에서 변수의 타입(type)은 고정되어 있지 않기 때문에 개발자가 원하면 자유롭게 바꿀 수 있다.

 

>>> no = 1
>>> type(no)
<class 'int'>
>>> no = "1"
>>> type(no)
<class 'str'>

위 코드를 보면 no 변수의 타입이 처음에는 int였다가 str으로 바뀐 것을 알 수 있다. 자바와 같은 정적(static) 프로그래밍 언어에서는 상상도 하기 힘든 일이며 이런 코드는 컴파일(compile)조차 되지 않는다.

 

/* java */
int no = 1;
no = "1"; // compile error!!

이렇게 유연한 파이썬의 타입 처리는 타입을 명시적으로 표시할 필요가 없기 때문에 파이썬으로 우리는 다른 언어에 비해 매우 간단명료한 코드를 작성할 수 있다.

 

타입 어노테이션/힌트?

타입에 대한 파이썬의 유연함은 일회성 스크립트나 소규모의 애플리케이션을 빠르게 개발할 때는 큰 장점으로 작용한다. 하지만 애플리케이션이 규모가 커지게 되면 이러한 파이썬의 다이나믹함이 치명적인 버그로 이어질 확률이 높아지게 되며 애플리케이션 안정성에 위험 요소가 되기도 한다. 따라서 중규모 이상의 파이썬 프로젝트에서는 소위 타입 힌팅(type hinting)이라는 개발 프로세스를 도입하여 사용하는 경우가 많다.

 

타입 힌팅(type hinting)은 말 그대로 파이썬 코드를 작성할 때 타입에 대한 메타 정보를 제공하는 것이다. 파이썬에 타입 힌팅이 추가되기 전에는 타입을 표시하려면 주석(comments)을 이용했어야 했다. 이 방법은 코드를 읽는 개발자에게는 약간의 도움이 될지는 모르겠으나 정해진 표준이 없었고 일반 주석과 구분이 어렵다.

 

num = 1  # type: int

def repeat(message, times = 2):
    # type: (str, int) -> list
    return [message] * times

 

반면에 타입 힌팅에서는 타입 어노테이션(annotation)이라는 새로운 방법으로 파이썬 코드의 타입 표시를 표준화한다. 따라서 코드 편집기(IDE)나 린터(linter)에서도 해석할 수 있도록 고안되었으며, 코드 자동 완성이나 정적 타입 체킹에도 활용되고 있다.

 

num: int = 1

def repeat(message: str, times: int = 2) -> list:
    return [message] * times

 

여기서 주의 사항은 타입 힌팅은 언어 레벨에서 실질적으로 어떠한 제약 사항도 강요되지 않는다는 것이다. 다시 말해, 변수나 함수에 추가한 타입 어노테이션이 부정확한다고 해서 경고나 오류가 발생하는 것은 아니다. 타입 힌팅(type hinting)은 우리가 작성한 코드를 다른 개발자가 읽기 수월하게 해주고, 우리가 사용하는 개발 도구가 활용할 수 있도록 도와줄 뿐이다. 

 

변수 타입 어노테이션

먼저 매우 간단한 변수에 타입 어노테이션을 추가하는 방법에 대해서 알아보겠습니다. 변수 이름 뒤에 콜론(:)을 붙이고 타입을 명시해주면 된다.

name: str = "John Doe"

age: int = 25

emails: list: ["john1@doe.com", "john2@doe.com"]

address: dict = {
  "street": "54560 Daugherty Brooks Suite 581",
  "city": "Stokesmouth",
  "state": "NM",
  "zip": "80556"
}

 

함수 타입 어노테이션

함수에 타입 힌탕을 적용할 때는 인자 타입과 반환 타입, 이렇게 두 곳에 추가해줄 수 있다.

인자에 타입 어노테이션을 추가할 때는 변수와 동일한 문법을 사용하며, 반환값에 대한 타입을 추가할 때는 화살표(->)를 사용한다.

def 함수명(<필수 인자>: <인자 타입>, <선택 인자>: <인자 타입> = <기본값>) -> <반환 타입>:
    ...
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:
    return "Hi! " + str

def repeat(message: str, times: int = 2) -> list:
    return [message] * times

참고로 콜론(:)과 화살표(->)를 사용할 때는 파이썬의 관행을 따라 콜론은 뒤에만 한 칸을 뛰우고, 화살표는 앞뒤로 한 칸을 띄운다.

 

typing 모듈

from typing import List, Set, Dict, Tuple
nums: List[int] = [1]
unique_nums: Set[int] = {6, 7}
vision: Dict[str, float] = {'left': 1.0, 'right': 0.9}
john: Tuple[int, str, List[float]] = (25, "John Doe", [1.0, 0.9])

 

사용자 정의 타입 힌팅

class User:
    ...

def find_user(id: str) -> User:
    ...

def create_user(user: User) -> User:
    ...

 

출처 : https://www.daleseo.com/python-type-annotations/

반응형

댓글