python_cleancode/ch05 at master · sajacaros/python_cleancode · GitHub
Skip to content

Latest commit

 

History

History

Folders and files

Readme.md

Chapter 5_데코레이터를 사용한 코드 개선

  • 데코레이터가 동작하는 방식 이해
  • 함수와 클래스에 적용되는 데코레이터를 구현하는 방법
  • 일반적인 실수를 피하고 효과적으로 구현하는 방법
  • 중복 회피(DRY 원칙 준수)
  • 관심사 분리
  • 좋은 데코레이터 사례
  • 좋은 선택이 될 수 있는 일반적인 상황, 관용구, 패턴

파이썬의 데코레이터

  • 문법적 설탕(syntax sugar)
    • 데코레이터 이후에 나오는 것을 데코레이터의 첫 번째 파라미터로 하고 데코레이터의 결과 값을 변환
      def original(...):
      ...
      original = modifier(original)
      
      @modifier
      def original(...):
      ...
      
      • modifier
        • 데코레이터
      • original
        • 데코레이팅된(decorated) 함수, 래필된(wrapped) 객체
  • 함수, 메서드, 제너레이터, 클래스에 적용 가능

함수 데코레이터

  • 활용 방안
    • 파라미터의 유효성 검사
    • 사전조건 검사
    • 기능 전체를 새롭게 정의
    • 서명을 변경
    • 원래 함수의 결과 캐시
    • 함수 데코레이터

클래스 데코레이터

  • 데코레터 함수의 파라미터로 함수가 아닌 클래스를 받음
    • 클래스 데코레이터가 복잡하고 가독성을 떨어뜨릴 수 있음
    • 장점
      • 코드 재사용과 DRY 원칙의 모든 이점 공유
      • 작고 간단한 클래스를 생성, 데코레이터로 기능 보강
      • 유지보수 시 데코레이터를 사용해 기존 로직을 훨씬 쉽게 변경
    • 리펙토링이 필요한 코드
      • 이벤트 클래스와 직렬화 클래스가 1:1로 매핑되어 있어서 클래스가 많아짐
      • password 필드를 숨기기 위한 기능이 유연하지 않음(타클래스에서 사용 불가)
      • serialize() 메서드는 모든 이벤트 클래스에 있어야 함
    • 리펙토링 후 코드

다른 유형의 데코레이터

  • 함수, 메서드, 클래스 뿐만 아니라 제너레이터, 코루틴에도 적용 가능
  • 이미 데코레이트된 객체도 제코레이트 가능
    @Serialization(
        username=show_original,
        password=hide_field,
        ip=show_original,
        timestamp=format_time
    )
    @dataclass
    class LoginEvent:
        username: str
        password: str
        ip: str
        timestamp: datetime
    
  • 코루틴으로 사용되는 제너레이터(227p)

데코레이터 인자 전달

  • 파라미터를 갖는 데코레이터를 구현하는 방법
    • 간접 참조(indirection)를 통해 새로운 레벨의 중첩 함수를 만듬
    • 데코레이터를 위한 클래스를 만듬
      • 일반적으로 중첩함수보다 가독성이 좋음
중첩 함수의 데코이레이터
  • 함수를 파라미터로 받아서 함수를 반환하는 함수
    • 고차 함수(higher-order function)
  • 파라미터를 받는 데코레이터 with 함수
    • 첫번째 함수
      • 파라미터를 받아서 내부 함수에 전달
    • 두번째 함수
      • 데코레이터가 될 함수
    • 세번째 함수
      • 데코레이팅의 결과를 반환하는 함수
데코레이터 객체

데코레이터 활용 우수 사례

  • 우수 사례
    • 파라미터 변환
    • 코드 추적
    • 파라미터 유효성 검사
    • 재시도 로직 구현
    • 일부 반복 작업을 데코레이터로 이동하여 클래스 단순화
파라미터 변환
  • 파라미터의 유효성 검사
  • 사전/사후 조건 강제
코드 추적
  • 실제 함수의 실행 경로 추적
  • 함수 지표 모니터링
  • 함수의 실행 시간 측정
  • 언제 함수가 실행되고 전달된 파라미터 로깅

데코레이터의 활용 - 흔한 실수 피하기

래핑된 원본 객체의 데이터 보존

  • 원본 함수의 일부 프로퍼티나 속성을 유지하지 않음

데코레이터 부작용 처리

#####데코레이터 부작용의 잘못된 처리

데코레이터 부작용의 활용

어느 곳에서나 동작하는 데코레이터 만들기

  • 데코레이터를 다른 유형에 적용하려고 하면 오류 발생
    • ex) 함수에 사용할 데코레이터를 메서드에 사용한 경우
    • 혼용 안되는 예
      • 클래스 메서드의 self 인자 부분에 문자열이 들어감
      • 두번째 인자에는 아무것도 전달하지 않음
  • 해결책
    • 데코레이터를 클래스 객체로 구현하고 __get__메서드를 구현한 디스크립터 객체를 만듬

데코레이터와 DRY 원칙

  • 신중하게 설계되지 않은 데코레이터는 코드의 복잡성을 증가 시킴
  • 재사용할 필요가 없을 경우 별개의 함수나 작은 클래스로도 충분함
  • 고려사항
    • 처음부터 데코레이터를 만들지 않음
    • 데코레이터가 적어도 3회 이상 필요한 경우에만 구현
    • 데코레이터 코드를 최소한으로 유지

데코레이터와 관심사의 분리

좋은 데코레이터 분석

  • 캡슐화와 관심사의 분리
  • 독립성
  • 재사용성
  • flask

요약