다들 알고 있는 것처럼, 파이썬은 동적 타입 언어이다. 이 것은 변수의 타입을 지정하지 않고, 모든 타입의 데이터를 넣을 수 있다는 말이다. 반면에 Java 와 같은 정적 타입 언어는 변수 선언시에 타입을 반드시 지정하고 해당 타입의 데이터만 넣을 수 있는데, 만약, 다른 타입의 데이터를 넣게 되면, IDE 등에서 에러표시를 해줄 것이며, 컴파일할 때에도 에러를 뿜어내고 컴파일 실패하게 된다.

public class Hello {
    public static void main(String[] args) {
        int num;
        // num = 10;
        num = "Hello Java";
        System.out.println(num);
    }
}

 

반면에, 파이썬은 다음처럼 아무런 문제가 없이 실행이 된다.

num = 1
print(type(num))
print(num);

num = "Hello Python"
print(type(num))
print(num);

 

어찌 보면, 파이썬의 이런 동적 타입 특성이 매우 편하게 다가옵니다. 일회성으로 빠르게 작성하거나, 소규모의 프로그램을 작성할 때에는 아주 큰 장점으로 작용하지만,  프로그램이 규모가 점점 커지면, 오히려 동적 타입이 에러를 유발하는 원인이 되어서 안정성에 위협적인 요소가 될 수 있다. 이런 이유때문에 정적 타입 언어를 선호하기도 한다. 예를 들어서 Javascript 도 Python 과 같은 동적타입언어인데, 이런 문제를 해결하고자 정적타입언어인 Typescript 를 만들어내기도 했다. 그러나, Typescript 는 완전한 정적타입언어여서 Javascript 의 가장 큰 장점인 유연함을 모두 빼앗아버렸다.

파이썬에서는 좀 더 멋진 방법을 제공하기 시작했는데, 바로 타입 힌팅이라는 것이다. 또는 타입 어노테이션 이라고도 한다. 파이썬 3.5 부터 지원하기 시작했다. 이것은 정적타입언어처럼 소스에 타입을 명시할 수 있도록 하였다. 

타입 힌트를 제공하여 여러가지 장점들이 생겼다. 일단 개발자가 보기에도 변수에 어떤 타입을 넣어야 할지를 알 수 있게 하였고, 코드편집기나 Linter 에서 해석을 할 수 있도록 하여서, 코드자동완성이나 타입체킹을 할 수 있게 되었다.

Visual Studio Code 의 설정에서 Type Checking Mode 를 켜준다.

num: int = 1
print(type(num))
print(num);

num = "Hello Python"
print(type(num))
print(num);

그러면, 위와 같이 num 에 int 형을 명시해주면, "Hello Python" 에 빨간 밑줄이 생겨서 타입에 문제가 있다고 표시해줄 것이다.

함수를 정의할 때에도 역시 인자와 리턴값에 타입을 명시해줄 수 있다.

name = "Tom"

def hello(msg):
    print(msg)

def hello2(msg: str) -> None:
    print(msg)

hello(name)
hello2(name)

 

여기에서 중요점이 한가지 있는데, 파이썬의 타입힌트강제사항이 아니라는 점입이다. 타입힌트는 사용해도 되고, 사용하지 않아도 상관이 없습니다. 그리고, 타입힌트를 사용한 경우에 다른 타입이 들어가더라도 파이썬 인터프리터는 아무런 문제 없이 실행까지 됩니다.

 

이제부터 파이썬에 타입힌트를 추가하는 법을 좀 더 구체적으로 알아봅시다. 우선, 변수에 타입힌트를 추가해보겠다.

member_no = 31

nick = "홍길동"

phones = ["010-1234-5678", "010-9876-4321"]

address = {
    "nation": "대한민국",
    "city": "서울",
    "gu": "강남구",
    "zipcode": "12345"
}

위의 코드는 아래와 같이 변경해볼 수 있다.

from typing import List, Dict

member_no: int = 31

nick: str = "홍길동"

phones: list[str] = ["010-1234-5678", "010-9876-4321"] # Python 3.9 이상
phones: List[str] = ["010-1234-5678", "010-9876-4321"] # Python 3.8 이하

# Python 3.9 이상
address: dict[str, str] = {
    "nation": "대한민국",
    "city": "서울",
    "gu": "강남구",
    "zipcode": "12345"
}

# Python 3.8 이하
address: Dict[str, str] = {
    "nation": "대한민국",
    "city": "서울",
    "gu": "강남구",
    "zipcode": "12345"
}

 

이번에는 함수에도 타입힌트를 적용해봅시다.

def print_name(name):
    ret_val = "당신의 이름은 " + name + 입니다.
    print(ret_val)
    return ret_val


def print2(str_val):
    print("좋은 세상이군! " + str_val + " 잘 살아보자")


def multiply(n1, n2=3.5):
    return n1 * n2


def make_list(msg, times=3):
    return [msg] * times

위의 코드는 아래와 같이 변경해 볼 수 있겠다.

def print_name(name: str) -> str:
    ret_val: str = "당신의 이름은 " + name + 입니다.
    print(ret_val)
    return ret_val


def print2(str_val: str) -> None:
    print("좋은 세상이군! " + str_val + " 잘 살아보자")


def multiply(n1: int, n2: float = 3.5) -> float:
    return n1 * n2


def make_list(msg: str, times: int = 3) -> list[str]:
    return [msg] * times

 

사용자 정의 타입의 클래스에도 타입힌트를 사용할 수 있다.

class Car:
    pass


def make_car(id: int) -> Car:
    return Car()


def fix_car(user: Car) -> Car:
    return Car()

 

여기까지 파이썬의 타입힌트에 대해서 알아보았다. 파이썬에서 타입힌트를 제공함으로써 코드 편집기에서 타입에 문제가 생기면 표시를 해주어서 타입 관련된 버그를 미리 찾아서 없앨 수 있어서 프로그램 유지보수에 아주 좋다. 그러면서도 강제적이지 않아서, 편하게 사용할 수 있다. 다른 동적타입언어서도 이런 타입힌트를 적용해주면 좋겠다. 예를 들어, Javascript 에도 꼭 적용이 되면 좋겠다. 앞으로 모든 파이썬 프로젝트에는 타입힌트를 꼭 적용해서 개발해야겠다.

 

 

 

+ Recent posts