지식이 늘었다/웹개발

Python 문법 Type Hinting

PurpleGuy101 2024. 12. 17. 11:44

0.

 

Type Hinting은 파이썬 3.5부터 생긴 기능이다.

 

C/C++이나 자바에서는 처음부터 함수의 데이터타입이 정해져있다.

C의 union이나 C++의 auto처럼 한번 꼬아서 생각해야하는 녀석들도 있지만..

 

기본적으로 C계열이나 Java들은 정적타입Statically Typed라고하여

변수 타입이 컴파일 될때부터 결정되어 있다.

 

하지만 Python은 동적타입Dynamically Typed라고 해서 변수 타입이 런타임에서 결정된다.

이러한 특성이 초보자에게는 편하게 느껴질지 모르지만

점점 프로그램이 복잡해질수록 어디에서 에러를 유발했는지 감도 안잡히게되어

불편해지는 요소가 된다.

 

데이터를 다루다보면 함수에서 값을 입력받아서 계산한 값을 리턴하는데..

이게 반환되는 값이 리스트형인지 튜플형인지 정수형인지 감이 안잡혀서

리턴값을 다른 함수에 막 넣었다가 오류가 발생하는 경험을 한번쯤 하게 될 것이다.

 

그러한 불편함을 극복하기 위해서 그나마 사용할 필요성을 느끼는 기능이

파이썬의 타입힌팅이다.

 

1.

 

아래의 간단한 함수를 실행해보자.

 

def list_avg(sequence):
    return sum(sequence) / len(sequence)

list_avg(123)

# line 2, in list_avg
#     return sum(sequence) / len(sequence)
# TypeError: 'int' object is not iterable

 

sequence를 정수 123으로 입력받았지만,

정수형은 iterable한 객체가 아니라 sum도 안되고, len도 안된다.

 

이러한 오류를 막기 위해서 아래와 같이 코드를 작성해줄 수 있다.

 

def list_avg(sequence:list) -> float:
    return sum(sequence) / len(sequence)

list_avg(123)

 

입력되는 파라미터의 옆에는 :list와 같이 콜론과 자료형을 적어주고, 

-> float과 같이 리턴되는 요소의 자료형을 적어주는 것이다.

 

 

2.

비록 파이썬 프로그램이 실행될때는 기능에 별다른 차이는 없지만

PyCharm이나 VSC같은 개발환경에서 여러가지 도움을 받을 수 있다.

 

PyCharm에서는 이러한 타입힌팅을 통해서

오류를 검출해서 경고도 날려준다.

 

지금은 VSC를 사용하고 있어서 IDE로 부터 별다른 도움을 받지 못했다.

mypy나 Pylance를 사용하여 정적 분석 도구를 따로 설정하고

Type Hinting을 통한 오류검출을 사용할 수 있다.

 

 

3.

이전에 작성한 Book Class에 대해서

Type Hinting을 추가한 코드이다.

Factory 기능을 수행하는 classmethod에서 리턴값을 Book이라는 클래스로 나타내야 하는데

그냥 Book이 아닌 인용마크 ("")를 단 "Book"을 사용한 것을 유의해야한다.

 

다른 클래스를 리턴할때는 인용마크가 필요없지만

자기자신의 클래스를 리턴할때는 인용마크를 달아줘야한다.

class Book:
    TYPES = ("hardcover", "paperback")

    def __init__(self, name:str, book_type: str, weight:int):
        self.name = name
        self.book_type = book_type
        self.weight = weight
    
    def __repr__(self) -> str:
        return f"<Book {self.name}, {self.book_type}, weighing {self.weight}g>"

    @classmethod
    def hardcover(cls, name: str, page_weight: int) -> "Book":
        return Book(name, Book.TYPES[0], page_weight +100)