본문 바로가기

About/Python

[Python] 어노테이션(Annotation) vs docstring

이전 포스팅에서 docstring과 어노테이션에 대해 다루어 봤는데, 이번 포스팅에서는 이 둘의 관계와 차이에 대하여 알아보겠습니다.

2022.03.10 - [About/Python] - [Python] Docstring에 대하여

2022.03.17 - [About/Python] - [Python] 어노테이션(Annotation)에 대하여

어노테이션은 docstring을 대체하는 것일까?

어노테이션이 소개되기 오래전부터 함수의 파라미터 또는 속성의 타입을 문서화할 때 docstring을 사용했었기 때문에 docstring 대신 어노테이션을 사용해야 하는 것인지에 의문을 가질 수 있습니다. 

대답은 "예" 입니다. docstring과 어노테이션은 서로 보완적인 개념이기 때문입니다.

docstring에 포함된 정보의 일부는 어노테이션으로 이동시킬 수 있는 것은 사실입니다. 하지만 docstring을 통해 보다 나은 문서화를 위한 여지를 남겨두어야 합니다. 특히 동적 데이터 타입과 중첩 데이터 타입의 경우 예상 데이터의 예제를 제공하여 어떤 형태의 데이터를 다루는지 제공하는 것이 좋습니다.

예를 들어 다음과 같이 데이터의 유효성을 검사하고 dict 값을 반환하는 함수가 있다고 가정하겠습니다.

1
2
3
4
def data_from_response(response: dict) -> dict:
    if response["status"!= 200:
        raise ValueError
    return {"data":response["payload"]}
cs

 

이 함수는 dict 형태의 파라미터를 받아서 dict 형태의 값을 반환합니다. 파라미터의 status 키의 값이 기댓값과 다른 경우 예외가 발생합니다. 그러나 상세한 내용은 알 수가 없는데, 예를 들어 response 객체의 올바른 인스턴스는 어떤 형태인지 결과의 객체는 어떤 형태인지 알 수 없습니다.

두 질문에 모두 대답하려면 파라미터와 함수 반환 값의 예상 형태를 docstring으로 문서화하는 것이 좋습니다.

다음은 docstring으로 위의 함수를 문서화한 예시입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def data_from_response(response: dict) -> dict:
    """response에 문제가 없다면 response의 payload를 반환
    
    - response dict의 예제::
    {
        "status" : 200, #int
        "timestamp" : "....", # 시간에 대한 ISO 포맷 문자열
        "payload" : { ... } # 반환하려는 dict 데이터
    }
    
    - 반환 값(dict)의 예제::
    {"data": { .. } }
    
    - 발생 가능한 예외:
    - HTTP status가 200이 아닌 경우 ValueError 발생
    """
    if response["status"!= 200:
        raise ValueError
    return {"data":response["payload"]}
cs

 

위의 예시로 보았을 때 함수의 입력 값과 반환 값에 대한 예상 형태를 더 잘 이해할 수 있습니다. 이 문서는 입출력 값을 더 잘 이해하기 위해서 뿐만 아니라 단위 테스트에서도 유용한 정보로 사용됩니다. 테스트용 입출력 값을 생성할 수도 있고 테스트의 성공 실패를 판단할 수도 있습니다.


위의 예시처럼 docstring과 어노테이션은 서로 보완적인 개념으로 혼합하여 사용하는 것이 가장 이상적으로 보입니다. 특히 docstring을 사용했을 때는 코드가 좀 더 커지게 된다는 점이 있지만, 상세한 내용의 제공으로 함수를 이해하는 것 뿐만 아니라 테스트에도 유용한 문서가 될 수 있습니다.

어노테이션과 docstring의 관계에 대하여 다루어 보았습니다.

참고사항