Dev.log

Python Type-Hints Package 본문

Python

Python Type-Hints Package

포켓몬빵 2022. 4. 12. 22:02

본 포스팅에서는 Python 3.5 이후의 버전에서 standard 라이브러리로 추가된 typing 패키지 및 type annotation과 이를 검사하는 mypy 패키지에 대해 진행해 보도록 하겠습니다.

 

Python의 변수는 동적 타입으로 하나의 변수에 여러 타입의 값을 할당할 수 있습니다. 즉, 변수에 값을 대입할 때, 굳이 타입을 선언해 줄 필요가 없습니다. 예를들어 Python에서 a = 1이라는 변수를 할당할때, a의 타입을 숫자형인 int 나 float으로 지정해 주지 않아도, python내에서 이를 숫자로 인식합니다. 하지만 이런 동적타입의 경우 코드의 길이가 길어지게되면 타입을 체크하는데 힘들어진다는 단점이 존재합니다.

 

이에 Python 3.5 버전 이후 부터 Type Annotation이나 typing 패키지를 통해 변수나 함수 파라미터와 반환값이 어떤 타입인지 코드 상에서 명시할 수 있게되었습니다. 하지만,  type annotation이나 typing 패키지를 사용한다고 해서 동적 타입인 파이썬을  Java와 같이 변수를 선언할 때 부터 타입을 지정해줘야 하는 정적 타입으로 만들어주지는 않습니다.

Type Annotation(타입 어노테이션)

동적 타입인 Python은 프로토타입과 같은 빠른 개발이 요구될때 큰 장점으로 작용하게됩니다. 하지만 개발의 규모가 커지면 이러한 동적 타입은 개발의 안전성에 위험 요소로 작용할 수 있습니다. 이에 초기 개발 이후의 파이썬 개발에 있어서 type hinting이라는 개발 프로세스를 도입하기도 합니다. Type hinting은 코드를 작성할때 아래와 같이 변수나 함수 파라미터 타입에 대한 메타정보를 제공해주는것을 의미합니다. 먼저 변수 타입 어노테이션을 추가하기 위해서는 위의 코드와 같이 변수 이름뒤에 콜론(:)을 붙인뒤 타입을 지정해 주면됩니다.

name: str = "john"
id : list: ["john@naver.com", "john1@naver.com"]
personal_details : dict = {"Country": "Korea", "city": "Seoul"}

또한, 함수 타입의 경우 먼저 파라미터에 타입 어노테이션을 변수와 동일한 문법인 콜론(:)을 통해 타입을 추가해주고, 반환값에 대해서는 화살표를(->) 통해 추가해 주면 됩니다.

def add(num1: int, num2: int) -> int :
    return num1 + num2

Typing Packages

Type annotation을 사용하다 보면 리스트, 딕셔너리, 튜플과 같은 파이썬 내장 자료 구조에 대한 타입을 명시해야 할 때가 있습니다. 이때 typing 패키지를 통해 타입 어노테이션을 추가할 수 있습니다.

from typing import List, Dict, Tuple, Set

num : List[int] = [1,2,3]
city : Dict[str,str] = {"Seoul" : "Korea", "Tokyo" : "Japan"}
id : Tuple[int,str,bool] = (82,"Seoul", True)
character : Set[str] = {"a","b","c"}

Final, Union, Optional

  • Final은 재할당이 불가능한 변수(상수 타입)에 대해 어노테이션을 추가할 때 사용할 수 있습니다.
  • Union은 여려개의 타입이 허용될수 있는 상황에 대해 어노테이션을 추가할때 사용할수 있습니다.
  • Optional은 None이 혀용되는 매개 변수에대한 어노테이션을 추가할때 사용할 수 있습니다.
from typing import Final, Union, Optional

def add(num: Final[int], nums: Final[int]) -> int:
    return num + nums

def toString(num: Union[int, float]) -> str:
    return str(num)
    
 def toString2(num: Optional[str] = None) -> str:
    return str(num)

Mypy

단순히 IDE상에서 경고를 띄워주는것으로 type hinting을 체크하기는 어려울수 있습니다. 이때 mypy라는 패키지를 사용할 수 있습니다. Mypy는 pypi에 올라와있는 패키지로 pip을 통해 설치 할 수 있습니다.

! pip install mypy

 

먼저 아래의 코드처럼 num의 어노테이션을 integer 형태로 지정한 반면, string 형태로 할당한 코드가 있다고 합시다.

num : int = "1"
print(num)

해당 코드를 python 인터프리터를 통해 실행시키면 아무 문제없이 돌아가게됩니다. 이는 위에서 언급한것과 같이  type annotation을 추가하였다해서 동적 타입인 파이썬을 정적 타입으로 만들어주지 않기 때문에 코드실행에 있어 아무런 영향이나 제약을 주지않습니다. 반면 mypy를 통해 위의 코드를 돌려보면, 변수의 타입과 지정된 변수의 타입이 다르다고 에러를 표출하게 됩니다. 이처럼 mypy를 통해 파이썬 인터프리터가 알지 못하는 타입 관련 에러를 찾아 낼 수 있습니다.

(env) C:\code>mypy test.py
test.py:1: error: Incompatible types in assignment (expression has type "str", variable has type "int")
Found 1 error in 1 file (checked 1 source file)
Comments