단단한 파이썬 3. 타입 어노테이션
- 프로그래밍 언어/파이썬
- 2023. 10. 8.
들어가기 전
이 글은 단단한 파이썬 3장을 공부하며 작성한 글입니다.
타입 어노테이션이란?
- 타입 어노테이션은 변수, 반환 값의 타입을 알려줌.
- 타입 어노테이션은 런타임 동안 파이썬에 아무런 영향을 주지 않음. (비용이 들지 않음)
- 타입 어노테이션은 개발자에게 의도를 전달하는 용도로 사용됨.
- 타입 어노테이션을 남발하는 것은 좋지 않음. (간결함을 잃음)
- number: int = 0 같은 타입 어노테이션은 무의미함.
def find_workers_available_for_time(open_time: datetime.datetime) -> list[str]:
workers = get_all_workers()
available_workers = [worker for worker in workers
if is_available(worker)]
if available_workers:
return available_workers
emergency_workers = [worker for worker in get_emergency_workers()
if is_available(worker)]
if emergency_workers:
return emergency_workers
return [OWNER]
이 코드에서 타입 어노테이션의 효용성은 다음과 같다.
- open_time (매개변수)가 어떤 타입인지를 알 수 있다. datetime인지 Unix Time인지는 이 함수를 쓰는 사람은 정확히 알 수 없는데, 명확해 짐.
- 함수 호출 결과로 여러 객체가 반환됨. 만약 반환 타입에 대한 어노테이션이 없었다면?
- get_all_workers(), get_emergencey_workers(), [OWNER]가 각각 무슨 값을 반환하는지 한 Depth 더 조사해야함.
타입 어노테이션의 장점
타입 어노테이션은 다음 두 가지 장점을 가진다.
- 자동완성 : 타입 어노테이션이 되어있다면, IDE에서 자동완성을 지원해 줌.
- 타입 체커 : 타입 체커를 통해 코드베이스의 견고성을 올려줄 수 있음.
타입 체커를 이용한 무결성 확인 : 타입 어노테이션 장점
"타입 체커"는 타입 어노테이션을 체크하고 타입 어노테이션이 잘못 사용된 것을 점검해주는 도구다. 타입 어노테이션과 타입 체커를 함께 이용하면 보다 단단한 코드를 작성할 수 있다.
# 3-2.py
def read_file_and_reverse_it(filename: str) -> str:
with open(filename) as f:
# 바이트로 인코딩.
return f.read().encode("utf-8")[::-1]
위의 코드와 실행 결과를 살펴보면 타입 체커의 효과를 알 수 있다.
- 반환 타입은 str이어야 하는데 byte 타입을 반환함.
- 타입 어노테이션이기 때문에 런타임에는 아무런 영향을 미치지 않음.
- 타입 체커를 실행해 미리 타입 체크를 하면 잘못 사용된 부분을 발견할 수 있음.
$ mypy 3-2.py
>>>
3-2.py:6: error: Incompatible return value type (got "bytes", expected "str") [return-value]
Found 1 error in 1 file (checked 1 source file)
타입체커는 정확하게 'str 타입을 반환해야하는데 byte 타입을 반환했다'라는 것을 알려준다. 이 외에도 여러가지 예시들을 살펴볼 수 있다.
def add_doubled_values(my_list: list[int]):
my_list.update([x*2 for x in my_list])
add_doubled_values([1, 2, 3])
>>>
3-3.py:3: error: "list[int]" has no attribute "update" [attr-defined]
Found 1 error in 1 file (checked 1 source file)
List 타입에 특정 Attribute가 없는 타입 에러도 타입체커(mypy)를 이용해서 검출할 수 있다.
ITALY = ['roma', 'pisa']
SPAIN = ['madrid']
def get_restaurant_name(city: str) -> str:
if city in ITALY:
return "Trattoria"
if city in SPAIN:
return "Hello restaurant"
return None
>>>
3-4.py:10: error: Incompatible return value type (got "None", expected "str") [return-value]
Found 1 error in 1 file (checked 1 source file)
위 경우도 타입체커가 문제를 검출해낸다. String 타입을 기대했는데, None Type이 반환되는 것도 있기 때문에 타입체커가 문제가 있는 것을 알게된 것이다.
타입 어노테이션을 사용할 때
타입체커는 정적 언어의 이점을 제공하지만, 여전히 파이썬이 동적 타입으로 동작할 수 있게 해준다. 그러나 타입 어노테이션을 사용하는 것 자체는 '새로운 비용'이기 때문에 필요한 경우에만 '잘' 사용하는 것이 중요하다. 그렇다면 타입 어노테이션과 타입 체커를 언제 사용하는 것이 좋을까?
- 다른 곳에서 호출할 가능성이 높은 공개 API
- 타입이 복잡한 곳, 비직관적인 곳을 강조하고 싶을 때
- mypy가 타입이 필요하다고 하는 경우.
타입 힌트는 '옵션'이다. 따라서 잠깐만 쓰일 코드에는 사용하지 않고, 오랫동안 사용될 코드라면 타입 힌트를 사용하는 것이 좋다. 타입체커와 타입 어노테이션을 적절하게 이용하면 다음의 이점을 가질 수 있다.
- 타입체커를 이용한 단단한 코딩
- 타입 어노테이션을 이용한 가독성 확보. (내부 Attribute를 더 잘 알 수 있게 됨.
'프로그래밍 언어 > 파이썬' 카테고리의 다른 글
단단한 파이썬 5. 컬렉션 타입 (1) | 2023.10.08 |
---|---|
단단한 파이썬 4. 타입의 제어 (0) | 2023.10.08 |
전문가를 위한 파이썬 7. 함수 데코레이터와 클로저 (1) | 2023.10.06 |
단단한 파이썬 8장 : Enum 사용하기 (0) | 2023.09.14 |
Python : asyncio의 시작과 종료 (0) | 2023.02.19 |