Pythonic code

·2022년 6월 21일
0

class의 pythonic 메서드

시퀀스 생성 메소드

  • python에서는 list에 대해 [::]와 같은 형태로 인덱싱을 표현할 수 있다.

  • 자체 시퀀스를 생성

    • __getitem____len__ 구현
    • 만약 클래스에 대해 인덱싱이 필요한 경우 리스트나 이터러블 객체를 새로 생성하는 것은 비효율 적이고, 위의 매직 메소드를 구현해서 자체 시퀀스를 생성한다.
    • collections.UserList를 상속할 수도 있다.

컨텍스트 관리자

  • 컨텍스트 관리자는 특정 동작 전후에 작업을 실행하도록 하는 python의 유용한 패턴이다.

    • e.g. http connection 연결 -> 특정 작업 -> 연결을 반환
    • with 과 함께 사용한다.
  • __exit__, __enter__ 메서드를 구현함으로써 클래스(객체)를 컨텍스트 관리자처럼 사용할 수 있다.

프로퍼티

  • 파이써닉한 게터세터 패턴이다
  • 다른 언어처럼 get_{....}처럼 value를 들고오고 set하는 것이 아니라,
    프로퍼티 데코레이터를 사용함으로써 변수 자체에 직접 접근하는 효과를 가질 수 있다. {property 변수}.setter로 property 변수를 수정, 저장하는 과정을 보호할 수 있다.

이터러블 객체

  • python에서는 for ~ in ~ 와 같은 형태의 구문을 자주 사용한다.
    • list, generator, set 등 대부분의 자료구조에 대해 사용할 수 있다.
  • 클래스에 __next__, __iter__ 메소드 중 하나를 가지는 경우 클래스는 이터러블하며 for 루프에서 사용가능하다.

컨테이너 객체

  • python에서 어떤 요소가 객체에 존재하는지 확인하는 in과 같은 문법은 직관성을 제공한다
  • 클래스에 __contains__ 메소드를 구현하면 클래스 객체를 이용해 코드를 직관적으로 작성할 수 있다.

디자인 원칙

계약에 의한 디자인

  • 함수의 입력 변수를 검증하는 작업은 항상 필요한데, 함수에 입력 변수를 넣기 전에 검증할 것인지, 입력된 변수에 대해 함수 안에서 검증할 것인지가 중요하다.
  • 사전조건은 코드가 실행되기 전에 체크해야하는 것이고, 사후조건은 함수 리턴 값에 대해서 체크해야한다.
  • 코드 전체에 대해 모두 사전조건을 따르게 하거나, 사후조건을 따르게 하는 등 통일 시키는 것이 좋고, 에러가 발생했을 때 책임 소재를 분명하게 할 수 있어 디버깅에 유리하다.

방어적 프로그래밍

  • 발생할 수 있는 에러에 대해서 처리하는 계획을 세우는 것이 중요하다.
    • 심각한 결함을 초래하는 경우 바로 프로그램을 중단해야하고,
    • 일반적인 결함은 예외를 발생시키기보다 로깅하는 것이 유리하다.
  • dict에 존재하지 않는 attribute에 직접 접근하는 경우 에러가 발생한다. 그러나 이 경우 dict.get({attribute}, default_value)를 이용해 어트리뷰트가 존재하는지 체크할 수 있다.
  • try-except블록은 자주 남용하거나 go-to를 구현하기 위해서 사용해서는 안되며 scope가 작아야 코드를 이해하기 쉽다.

관심사의 분리: 캡슐화

  • 객체는 잘 정의되어야 하고 가능하면 한가지 일만 수행할 정도로 작은 것이 좋다.
  • 객체 사이의 의존성이 낮은 것이 좋다.

개발 지침

  • DRY: 같은 코드가 여러 곳에 존재하는 것은 비효율적이며, 수정 한번에 모든 코드를 수정해야 하므로 바람직하지 않다.
  • YAGNI: 과잉 엔지니어링을 하지 않도록 한다.
  • EAFB/LBYL: EAFP는 허락보다 용서를 구하기 쉽다는 뜻으로 우선 코드를 실행하고 실제 동작하지 않는 경우 대응하는 방법이다. pythonic한 방법은 EAFB가 유리하다.
profile
Ben

0개의 댓글