soma0sd

코딩 & 과학 & 교육

Python 패키지 개발일지 04: 알기쉬운 파이썬 코드

반응형

Python은 "일단 작동은 하는 코드"와 "한눈에 기능을 알아볼 수 있는 코드"의 차이가 있습니다. 코딩할 때 알아보기 쉬운 방식으로 코드를 작성하면 유지관리에 도움이 됩니다. 또한, Sphinx를 사용해서 문서화를 할 때 엄청난 이득을 얻게 됩니다.

이름 짓기

사실 쉬운일은 아닙니다

예전과는 달리 VSCode와 같은 똑똑한 에디터들은 패키지를 가져오면 자동으로 모듈과 함수, 클래스의 이름을 가져옵니다. 마침표(.)를 입력하면 자동으로 선택메뉴가 나오고 화살표키로 선택한 뒤 엔터로 자동입력하는 방식이죠.

VSCode의 지능형 코드완성

이 지능형 코드 완성(IntelliSense)기능을 최대한 활용하면 매번 패키지 소스코드를 들추지 않아도, 레퍼런스 문서를 뒤적이지 않아도 다음 일을 진행할 수 있으니 이 기능을 가진 편집기들을 많은 사람들이 사용하고 있습니다. 즉, 많은 사람들이 이름을 보고 바로 알 수 있는 이름을 사용하는 것이 좋습니다.

이름 규칙: 대소문자 규칙

구글 스타일가이드는 특성에 따른 이름규칙을 추천합니다. 기본적으로 스네이크 표기법(snake_case)으로 이름을 짓고, 내부에서만 사용하는 값일 경우에는 밑줄(_)로 시작하며 이중밑줄을 사용하지 않습니다.

종류 예시(내부) 표기법
패키지 lower_with_under 스네이크 표기
모듈 lower_with_under (_lower_with_under) 스네이크 표기
클래스 CapWords (_CapWords) 파스칼 표기
예외 CapWords 파스칼 표기
함수 lower_with_under() (_lower_with_under()) 스네이크 표기
상수 CAPS_WITH_UNDER (_CAPS_WITH_UNDER) 스네이크 표기(대문자)
변수 lower_with_under (_lower_with_under) 스네이크 표기
매개변수 lower_with_under 스네이크 표기

get과 set을 합치기

class MyClass:
    def __init__(self, a):
        self._a = a

    def get_a(self):
      return self._a

    def set_a(self, a):
      self._a = a

if __name__ == '__main__':
    mc = MyClass(16)
    print(mc.get_a())  # 16
    mc.set_a(26)
    print(mc.get_a())  # 26

클래스를 만들다보면 필요에 의해서 이것저것 추가하다 보니 get_, set_이 생기는 경우가 있습니다.

class MyClass:
    def __init__(self, a):
        self._a = a

    def a(self, a=None):
        self._a = self._a if a is None else a
        return self._a

if __name__ == '__main__':
    mc = MyClass(16)
    print(mc.a())  # 16
    print(mc.a(26))  # 26

이렇게 하나의 메소드로 줄이는 편이 깔끔합니다.

class MyClass:
    def __init__(self, a):
        self._a = a

    @property
    def a(self): return self._a

    @a.setter
    def a(self, a):
        self._a = a

    @property
    def b(self): return self._a * 2

if __name__ == '__main__':
    mc = MyClass(16)
    print(mc.a)  # 16
    mc.a = 26
    print(mc.a)  # 26
    print(mc.b)
    mc.b = 6  # 오류: AttributeError

복잡하지 않은 클래스의 속성을 다루거나 사용자가 이용은 할 수 있지만 변경할 수는 없는 값을 다룰 때는 @property를 활용하는 것도 좋습니다. IntelliSense는 property와 setter를 묶어서 보여주기 때문에 설명을 여러 번 할 필요도 없습니다.

유형 표시

함수나 클래스의 멤버함수의 매개변수, 출력값의 유형을 표시하면 IntelliSense가 유형을 자동으로 읽어 매개변수의 내부 함수나 특성을 끝까지 추적할 수 있도록 해줍니다. 또한 이름에 표현해야 할 요소를 효과적으로 줄여줄 수 있습니다.

매개변수에 유형 표시

def float_number_print(number):
    print("{:.3f}".format(number))

이것은 실수형 매개변수를 받아와서 터미널에 출력합니다. 실수형 변수가 아니라면 print의 포맷변환이 안된다고 오류를 표시할겁니다. 매개변수로 어떤 것을 요구하는지 표시한다면 파이썬은 Print가 잘못된 것이 아니라 함수에 들어갈 값이 잘못되었다고 알려줄 것입니다.

def float_number_print(number: float):
    print("{:.3f}".format(number))

출력값 유형 표시

def round(number: float) -> int:
    _p = number - int(number)
    if _p >= 0.5:
        return int(number + 1)
    else:
        return int(number)

예시처럼 출력값 유형을 표시할 수 있습니다. 출력 유형 표시는 IntelliSense에도 영향을 미치며, 읽기에도 좋습니다.

def round(number: float) -> int:

코드 접기(code folding)를 지원하는 편집기를 사용하는 경우 위의 예시처럼 보이게 됩니다. 이렇게 입출력 정보를 첫 줄에 표시하면 소스코드의 유지관리도 편해집니다.

반응형
태그:

댓글

End of content

No more pages to load