데이터 공부/Python

파이썬 클린코드 (1) - 코드 포매팅과 도구

한소희DE 2023. 1. 25. 21:19
요즘 파이썬 클린코드(마리아노 아나야 지음) 라는 책을 읽고 있다.
한 챕터씩, 책을 읽으며 내가 이해한 대로 요약 및 정리를 해보도록 하겠다.

 

목차

 

1. 클린코드란?

1-1. 클린코드의 중요성

1-2. 클린코드를 위한 코드 포맷팅

 

2. 클린 코드를 위한 방법 - 문서화

2-1. Docstring

2-2. Annotation

 

3. Annotation은 Docstring을 대체하는 것일까?

4. 클린 코드를 위한 방법 - 도구 설정

5. 1장 요약

 

 

 


 

 

 

1. 클린코드란?

코딩 표준, 포맷팅, 린팅 도구나 다른 검사 도구를 사용한 코드 레이아웃 설정과 같은 것 그 이상을 의미한다.

즉, 품질 좋은 소프트웨어를 개발하기 위해 견고하고 유지보수가 쉬운 시스템을 만들기 위한 요소다.

 

1-1. 클린코드의 중요성

소프트웨어 요구사항이 변경됐을 시, 수정이 가능하도록 코드를 구성해야 하기 때문에 클린 코드는 중요하다.

 

1-2. 클린코드를 위한 코드 포맷팅

대표적으로는 PEP-8 이 있다. PEP-8이란, 대표적인 Python Code 개선 제안 문서다.

이러한 가이드라인에 따라 코드를 구조화하면 아래와 같은 장점을 얻을 수 있다.

 

  • 검색을 효율적으로 할 수 있게 도움
  • 일관성 있기 때문에 읽기가 쉬움
  • 한 눈에 코드를 이해하고, 버그 및 실수를 쉽게 찾을 수 있음
  • 잠재적 버그를 찾기 용이하여, 결과적으로 코드 품질이 향상

 


 

2. 클린 코드를 위한 방법 - 문서화

 

훌륭한 코드는 문서화도 잘 돼있다고 한다.

주석도 문서화인가? 
문서화는 주석이랑 다르다.
주석은, 명확하게 이름을 지어서 주석을 최소화하는 게 가장 좋다. 그리고 해당 코드 자체가 문서화되어있어야 한다.
코드 자체가 주석처리된 것은 올바르게 코드가 작성되지 않았다는 징후다. 코드 주석은 피할 수 있으면 무조건 피해야 한다.

 

 

문서화는 크게 Docstring과 Annotation으로 나뉜다.

 

 

2-1. Docstring

Docstring이란? 소스코드에 포함된 문서를 의미한다.

 

def my_func():
	"""Docstring"""
    return None

 

 

만약 위 코드에 대해서, __doc__ 을 출력하면 Docstring 값을 얻을 수 있다.

 

>> my_function.__doc__ # 또는 help(my_function)
'Docstring'

 

 

Docstring 작성은 좋은 습관이라고 한다. 특히, 아래와 같은 장점을 얻을 수 있다.

  • 해당 컴포넌트가 어떻게 설계됐는지 힌트를 줄 수 있다.
  • 파이썬이 동적인 데이터 타입을 지니기 때문에, 입출력 정보가 어떻게 동작할지 이해하는 도구가 된다.

 

 

 

2-2. Annotation

Annotation이란, 코드 사용자에게 함수 인자로 어떤 것이 와야 하는지 힌트를 주는 것을 뜻한다.

 

즉, 타입 힌팅을 활성화한다. 하지만, Annotation을 썼다고 해서는 파이썬이 타입을 강제하지는 않는다는 점을 참고하자.

 

 

# Before
def my_function(value):
...

# After
from typing import Tuple
Value = Tuple[int, str]
def my_function(value: Value):
...

 

 

Annotation을 쓰면, __annotations__ 이 활성화된다.

이 정보로 문서를 생성하거나, 유효성을 검증하는 데에 이용하거나, 타입을 체크할 수 있다.

만약 위 예시의 코드에 대한 __annotations__ 를 확인하려면, 아래와 같이 체크할 수 있다.

 

>> my_function.__annotations__
{'value': typing.Tuple[int, str]}

 


 

3. Annotation은 Docstring을 대체하는 것일까?

대체가 가능하다. 하지만 100% 대체는 아니고, 어노테이션만 쓰면 상세한 내용은 알 수가 없기 때문에, annotation을 위주로 작성하되 docstring을 더함으로써 보다 나은 문서화를 위한 여지를 남겨두어야 한다고 한다.

 

 

아래는 책에서 다룬 예제다.

 

def data_from_response(response: dict) -> dict:
    """response에 문제가 없다면 response의 payload를 반환
    
    - response 사전의 예제::
    {
        "status": 200, # <int>
        "timestamp": "...", # 현재 시간의 ISO 포맷 문자열
        "payload": {...} # 반환하려는 사전 데이터
    }
    
    - 반환 사전 값의 예제::
    {"data": {..}}
    
    - 발생 가능한 예외:
    - HTTP status 가 200이 아닌 경우 ValueError 발생
    """
    if response["status"] != 200:
        raise ValueError
    return {"data": response["payload"]}

 

 

이런 식으로, annotation 위주로 type hint를 주고 추가 설명을 Docstring을 통해 보완할 수 있다.

 

이것에 대한 docstringannotation아웃풋은 아래와 같다. 

 

>> data_from_response.__annotations__
{'response': <class 'dict'>, 'return': <class 'dict'>}


>> data_from_response.__doc__
response에 문제가 없다면 response의 payload를 반환

    - response 사전의 예제::
    {
        "status": 200, # <int>
        "timestamp": "...", # 현재 시간의 ISO 포맷 문자열
        "payload": {...} # 반환하려는 사전 데이터
    }

    - 반환 사전 값의 예제::
    {"data": {..}}

    - 발생 가능한 예외:
    - HTTP status 가 200이 아닌 경우 ValueError 발생

 



4. 클린 코드를 위한 방법 - 도구 설정

 

앞서 Annotation을 통한 Type Hint를 알아봤다. 하지만, Annotation 만 썼다고 해서 이것 만으로는 강제성을 띄지 않는다.

이때, 특정한 도구를 설정하면 Annotation 설정만으로 데이터 타입의 유효성을 검사해주기도 한다.

 

이처럼, 도구 설정을 통해 타입 일관성 검사, 일반적인 코드 검증 등을 '도구 설정'을 통해 쉽게 할 수 있다. 이 책에서 다룬 몇 가지의 도구 일부를 소개해보겠다.

설명 도구
타입 일관성 검사 mypy
코드를 분석하여 PEP 8에 가까운 스타일로 코드 검증 pylint
팀에서 논의된 코드 컨벤션대로 코드를 자동 포맷팅할 수 있도록 도움 black

 

 


 

5. 1장 요약

즉, 클린코드는 가독성과 유지보수성, 타인의 코드 이해도를 높이는 효과적인 코드 작성 방법이기에 중요하다.

코딩 스타일이나 가이드라인 검사가 자동화시키면 관리에 수월하기 때문에, mypy, pylint, black 등과 같은 도구를 구성하는 방법도 고민해보면 좋다.