티스토리 뷰

파이썬의 타입 어노테이션(type annotation)에 대해서 알아보자. 타입 어노테이션에 대해서 알기 위해선 우선 파이썬의 특징을 잠시 알아하고 왜 타입 어노테이션이 필요한지 설명하겠다.

 

 

# 파이썬은 동적 타입 언어다

 

a = 1
a = '1'

파이썬은 식별자에 값을 넣으면 아주 쉽게 변수를 만들 수 있다. 그리고 어떤 값이든 넣을 수 있다. 위에서 a에 int 타입인 1을 넣었고, 바로 str 타입인 '1'을 넣었다. 이렇게 식별자에 타입을 정하지 않고 실행 중에 타입을 확인하는 프로그래밍 언어를 동적 타입 언어라고 한다.

 

 

# 파이썬은 덕 타이핑을 쉽게 할 수 있다

이런 동적 타입 언어의 기능으로 파이썬은 정말 쉽게 코드를 작성할 수 있게 된다. 예를 들어 다음은 컬렉션의 요소를 출력하는 함수다.

def print_items(items):
    for item in items:
        print(item)

 

 

print_items() 함수의 매개변수인 items는 타입이 없다. 따라서 print_items()에 어떠한 타입을 다 전달할 수 있다. 이것을 덕 타이핑이라고 한다. 덕 타이핑은 프로그래밍 언어에서 특정 인터페이스를 갖고 있다면 어떤 타입이든 사용할 수 있는 것을 의미한다. for-in은 __iter__ 메서드만 있으면 사용할 수 있다.

 

list, set, dict는 __iter__ 메서드가 정의되어 있으므로 print_items()에 문제없이 실행이 된다.

print_items([1,2,3])
print_items({4,5,6})
print_items({"a":1, "b":2, "c": 3})

 

 

# 동적 타입은 양날의 검과 같다

하지만 이렇게 편한 동적 기능이 독이 될 수도 있다. 예를 들어서 for-in으로 실행할 수 없는 1을 전달하면 어떻게 될까?

print_items(1)

print_items()는 매개변수가 어떤 타입이 될지 정보를 갖고 있지 않기 때문에 런타임이 되어서야 이를 알 수 있다. int 타입인 1은 __iter__ 메서드가 존재하지 않기 때문에 에러가 발생하고 프로그램이 종료될 것이다.

 

여기서 동적 타입의 단점이 발생한다. 코드가 간단하다면 문제가 없지만, 코드가 복잡해질수록 이런 문제가 발생할 가능성이 커진다. 모든 코드는 변할 수밖에 없기 때문이다.

 

 

# 타입 어노테이션 도입

타입 어노테이션은 파이썬 3.5에 도입되었다. 타입 어노테이션은 타입을 알려주는 힌트가 된다. (힌트라는 말을 기억하자)

a: int = 1

 

 

처음 타입 어노테이션이 도입되었을 때, 개발자들은 자바나 C++처럼 정적 타입 언어로 되는 것이 아닐지 두려워했다. 하지만 타입 어노테이션은 힌트일 뿐이며, 타입 어노테이션의 사용은 선택 사항일 뿐이다.

 

그리고 타입 어노테이션은 런타임 시 주석처럼 처리되어서 실제 동작에는 전혀 영향을 미치지 않는다. 심지어 아래와 같이 다른 타입을 넣어도 문제가 되지 않는다.

a: int = '1'

 

 

# 그럼 타입 어노테이션이 힌트라면 왜 사용할까?

타입 어노테이션은 다른 툴과 사용하면 시너지가 발생한다. 바로 자동 완성 기능과 타입 체커이다.

 

## 자동 완성 기능

파이썬은 동적 타입 언어이기 때문에 어떤 타입일지 예측하기가 쉽지 않다. 하지만 타입 어노테이션이 되어 있다면 IDE들은 타입을 쉽게 예측하고 자동 완성 기능을 제공하게 된다.

 

예를 들어 vscode에서 아래 코드의 str 타입이 무엇인지 추론하지 못한다.

def my_func(str):
    str # str의 타입은?

그래서 아래처럼 자동 완성 기능이 작동하지 않는다.

vscode에서 str의 타입을 추론하지 못하고 있다.

하지만 타입 어노테이션으로 str이 문자열 타입임을 명시하면 아래와 같이 자동 완성 기능이 작동한다.

타입 어노테이션 때문에 vscode가 str의 타입을 추론할 수 있게 되었다.

 

## 타입 체커

코드에 명시된 타입 어노테이션을 이용해서 타입이 잘못 사용되는 곳이 없는지 확인할 수 있으면 좋을 것이다. 이때 사용하는 도구가 타입 체커이다. mypy는 제일 많이 사용되는 타입 체커이다.

 

mypy는 정적 분석도구이기 때문에 소스코드에서 분석이 일어나며, 런타임에는 전혀 영향을 미치지 않는다.

a: int = 1
a = '1'

 

위의 파일을 main.py로 저장하고 mypy로 실행시켜 보자.

mypy main.py
main.py:2: error: Incompatible types in assignment
    (expression has type "str", variable has type "int")  [assignment]
Found 1 error in 1 file (checked 1 source file)

2번째 줄에서 int 변수에 str 타입을 사용했다는 에러를 알려준다. 이처럼 타입 어노테이션과 타입 체커를 사용하면 타입이 불일치하는 오류를 쉽게 찾을 수 있게 된다. 타입 체커를 사용하면 오류를 조기에 발견할 수 있기 때문에 시간과 비용을 절약할 수 있게 된다.

 

 

# 타입 어노테이션을 꼭 사용해야 할까?

타입 어노테이션을 사용하면 자동 완성 기능을 통해서 타이핑이 쉬워지고, 타입 체커를 통해서 사전에 버그를 제거할 수 있기 때문이다. 하지만 타입 어노테이션은 강제가 아니다. 선택 사항이다. 결국 타입 어노테이션의 사용은 개발자가 결정해야 할 문제라고 할 수 있다.

 

간단한 코드나 잠시 사용하고 버려질 코드에는 타입 어노테이션을 사용하지 않는 게 기존의 파이썬의 편리함을 그대로 유지할 것이다. 반대로 복잡한 코드와 오래 사용할 코드는 타입 어노테이션을 사용함으로써 더 튼튼한 코드가 될 것이다.

 

댓글
공지사항