“파이썬 타입 어노테이션“은 변수, 함수 매개변수, 함수 반환 값 등에 대한 타입 정보를 코드에 명시적으로 추가하는 기능입니다. 이는 코드의 가독성을 높이고, 협업 시 코드의 이해와 유지보수를 용이하게 만들어줍니다.
타입 어노테이션은 주로 변수 뒤에 콜론(:)을 사용하여 타입을 명시합니다.
함수의 매개변수에 대해서도 마찬가지 방식으로 사용됩니다.
반환값만 -> 를 사용하여 명시합니다.
기본 사용법은 아래와 같습니다.
기본 사용법
# 변수에 대한 타입 어노테이션
name: str = "John"
age: int = 25
height: float = 175.5
# 함수 매개변수와 반환 값에 대한 타입 어노테이션
def greet_person(person_name: str, person_age: int) -> str:
greeting = f"Hello, {person_name}! You are {person_age} years old."
return greeting
# 함수 호출
result = greet_person(name, age)
print(result)
파이썬 타입 어노테이션 장점
주요 이점 | 설명 |
---|---|
가독성 향상 | 명시적인 타입 정보를 통해 코드를 이해하기 쉽게 만듭니다. |
타입 검사 도구 활용 | 타입 검사 도구를 사용하여 코드의 타입 일치성을 검사하고 버그를 방지할 수 있습니다. |
문서화 향상 | 코드의 동작과 함께 예상되는 타입 정보를 문서화하여 문서의 품질을 높입니다. |
파이썬 타입 어노테이션 이용시 주의점
주의점 | 설명 |
---|---|
동적 타이핑과 조화 | 파이썬은 동적 타이핑 언어이므로, 타입 어노테이션은 코드 가독성을 높이는데 활용되지만 런타임에는 영향을 미치지 않음. |
필수는 아님 | 타입 어노테이션은 필수가 아니며, 코드의 명확성을 해치지 않을 경우 생략 가능. |
버전 | Python 3.5 이상의 버전을 사용하여 타입 어노테이션을 활용. 3.9 버전 이상 부터는 typing 모듈이 필요 없음 |
기본적인 타입 힌트
List, Tuple, Dict, Set
이들은 각각 리스트, 튜플, 딕셔너리, 세트를 나타내는 타입 힌트입니다.
from typing import List, Dict, Tuple, Callable
def process_data(data: List[int]) -> Dict[str, Tuple[int, Callable]]:
result = {}
for value in data:
result[f"key_{value}"] = (value, lambda x: x * 2)
return result
위의 주의점에 언급했지만 기본적인 타입 힌트는 3.9이상 버전 부터는 typing 모듈이 필요 없습니다.
위와 동일한 type annotation을 typing 모듈 없이 아래와 같이 구현 할 수 있습니다.
def process_data(data: list[int]) -> dict[str, tuple[int, callable]]:
result = {}
for value in data:
result[f"key_{value}"] = (value, lambda x: x * 2)
return result
numpy
나 DataFrame
에서도 아래와 같이 type annotation을 사용할 수 있습니다.
from typing import List, Tuple
import numpy as np
# 1D 배열
array_1d: np.ndarray[float] = np.array([1.0, 2.0, 3.0])
# 2D 배열
array_2d: np.ndarray[List[float]] = np.array([[1.0, 2.0], [3.0, 4.0]])
# 다차원 배열
array_3d: np.ndarray[List[List[float]]] = np.array([[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]])
# 데이터프레임
data_frame: pd.DataFrame[int, str] = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['X', 'Y', 'Z'])
# 시리즈
series: pd.Series[str] = pd.Series(['apple', 'banana', 'cherry'], index=['A', 'B', 'C'])
# 딕셔너리를 활용한 데이터프레임
data_frame_dict: pd.DataFrame[Dict[str, int]] = pd.DataFrame({'A': {'X': 1, 'Y': 2, 'Z': 3}, 'B': {'X': 4, 'Y': 5, 'Z': 6}})
Optional
어떤 타입 또는 None
을 나타내는 타입 힌트로, 예외 상황에 유용합니다.
from typing import Optional
def find_item(name: str) -> Optional[str]:
# 아이템을 찾으면 해당 아이템, 찾지 못하면 None 반환
pass
Union
여러 타입 중 하나일 수 있는 타입을 표현합니다.
from typing import Union
def process_input(data: Union[str, List[int]]) -> None:
# 함수 내용
pass
Generic
클래스나 함수에서 제네릭을 사용하여 임의의 타입을 나타낼 수 있습니다.
from typing import TypeVar, Generic
T = TypeVar('T')
class Box(Generic[T]):
def __init__(self, content: T):
self.content = content
string_box = Box("Hello, World!")
int_box = Box(42)
위의 코드에서 T
는 임의의 타입을 의미하며, Box
클래스를 사용할 때에는 어떤 타입이든 넣을 수 있습니다.
callable
Callable은 함수의 타입을 표현할 때 사용됩니다. 매개변수와 반환 값의 타입을 정의하여 함수의 모양을 명시할 수 있습니다.
from typing import Callable
def apply_operation(operation: Callable[[int, int], int], a: int, b: int) -> int:
return operation(a, b)
# 덧셈 함수를 만들어 적용해보자
def add(x: int, y: int) -> int:
return x + y
result = apply_operation(add, 3, 4) # 3 + 4 = 7
Callable
: 이 타입은 함수를 나타냅니다.[int, int]
: 함수의 매개변수로 두 개의int
타입을 받는다는 것을 의미합니다.int
: 함수의 반환 값이int
타입이라는 것을 나타냅니다.
그래서 Callable[[int, int], int]
은 “두 개의 정수를 받아 하나의 정수를 반환하는 함수”를 의미합니다.
a: int, b: int
:- 이 부분은 함수를 호출할 때 사용되는 인자의 타입을 지정합니다.
- 여기서
a
와b
는 각각int
타입이어야 한다는 것을 나타냅니다.
이 두 가지 정보를 동시에 사용하는 것은 반드시 필요하지는 않습니다.
마치며
typing
모듈은 파이썬 코드를 더 강력하고 안정적으로 만드는 데에 큰 도움이 될 것 같습니다.
특히 Optional
과 Union
기능은 필요한 순간에 유용하게 쓰일 것 같습니다.
typing
모듈을 몰랐을 때는 함수가 길어질 때만 매개변수와 리턴에만 간단히 몇 번 사용했는데, 복잡한 자료형의 데이터 타입을 명시하는데도 사용할 것 같습니다.