• 티스토리 홈
  • 프로필사진
    31514
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
31514
  • 프로필사진
    31514
    • 분류 전체보기 (107)
      • Book (66)
        • Learning SQL (9)
        • SQL 레벨업 (8)
        • 견고한 데이터 엔지니어링 (5)
        • 운영체제 (2)
        • 스파크 완벽 가이드 (9)
        • 파이썬 코딩의 기술 (29)
        • 분산 컴퓨팅 (4)
      • 개발 (25)
      • 기타 (10)
        • 출퇴근 공부 간단 정리 (7)
      • ELK (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
      • 31514의 이전 블로그는 여기로!
      등록된 공지가 없습니다.
    # Home
    # 공지사항
    #
    # 태그
    # 검색결과
    # 방명록
    • [BW 26] functools.wrap을 사용해 함수 데코레이터를 정의하라
      2024년 10월 25일
      • 31514
      • 작성자
      • 2024.10.25.:47

      데코레이터는 자신이 감싸고 있는 함수가 호출되기 전과 후에 코드를 추가로 실행해준다.

      즉, 데코레이터가 자신이 감싸고 있는 함수의 입력 인자, 반환 값, 함수에서 발생한 오류에 접근할 수 있다는 뜻이다.

       

      예를 들어 함수가 호출될 때마다 인자 값과 반환 값을 출력하는 함수가 있다고 하자.

      def trace(func):
          def wrapper(*args, **kwargs):
              result = func(*args, **kwargs)
              print(f'{func.__name__}({args!r}, {kwargs!r}'
                    f'-> {result!r}')
              return result
          return wrapper

       

      그리고 피보나치 함수를 정의하고 trace 함수의 인자로 피보나치 함수를 입력할 수도 있지만,

      def fibonacci(n):
          """n번째 피보나치 수를 반환한다."""
          if n in (0, 1):
              return n
          return (fibonacci(n - 2) + fibonacci(n - 1))
          
      fibonacci = trace(fibonacci)

       

       

      애초에 함수를 정의할 때, 데코레이터를 사용할 수도 있다.

      @trace
      def fibonacci(n):
          """n번째 피보나치 수를 반환한다."""
          if n in (0, 1):
              return n
          return (fibonacci(n - 2) + fibonacci(n - 1))

       

      이를 실행하면 다음과 같다.

      fibonacci(3)
      
      >>>
      fibonacci((1,), {}-> 1
      fibonacci((0,), {}-> 0
      fibonacci((1,), {}-> 1
      fibonacci((2,), {}-> 1
      fibonacci((3,), {}-> 2

       

      하지만 데코레이터를 사용한 함수의 이름이 피보나치가 아닌게 된다.

      print(fibonacci)
      
      >>>
      <function trace.<locals>.wrapper at 0x1049f0b80>

       

      

      만약 데코레이터를 사용하지 않았더라면 다음과 같은 결과가 나왔을 것이다.

      <function fibonacci at 0x10288ce00>

       

       

      그리고 help 내장 함수의 경우도 마찬가지다. 피보나치 함수에 정의된 Docstring이 출력되지 않는다.

      help(fibonacci)
      
      # 데코레이션을 사용하지 않은 경우
      >>>
      Help on function fibonacci in module __main__:
      
      fibonacci(n)
          n번째 피보나치 수를 반환한다.
          
      # 데코레이션을 사용한 경우
      >>>
      Help on function wrapper in module __main__:
      
      wrapper(*args, **kwargs)

       

      문제의 원인은 trace 함수가 자신의 본문에 정의된 wrapper 함수를 반환하기 때문이다.

      이를 해결하기 위해 functools 내장 모듈에 정의된 wraps 도우미 함수를 사용할 수 있다.

      from functools import wraps
      
      def trace(func):
          @wraps(func)
          def wrapper(*args, **kwargs):
              result = func(*args, **kwargs)
              print(f'{func.__name__}({args!r}, {kwargs!r}'
                    f'-> {result!r}')
              return result
          return wrapper

      'Book > 파이썬 코딩의 기술' 카테고리의 다른 글

      [BW 28] 컴프리헨션 내부에 제어 하위 식을 세 개 이상 사용하지 말라  (0) 2024.10.28
      [BW 27] map과 filter 대신 컴프리헨션을 사용하라  (0) 2024.10.28
      [BW 25] 위치로만 인자를 지정하게 하거나 키워드로만 인자를 지정하게 해서 함수 호출을 명확하게 만들라  (0) 2024.10.24
      [BW 24] None과 독스트링을 사용해 동적인 디폴트 인자를 지정하라  (0) 2024.10.23
      [BW 23] 키워드 인자로 선택적인 기능을 제공하라  (0) 2024.10.23
      다음글
      다음 글이 없습니다.
      이전글
      이전 글이 없습니다.
      댓글
    조회된 결과가 없습니다.
    스킨 업데이트 안내
    현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
    ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
    목차
    표시할 목차가 없습니다.
      • 안녕하세요
      • 감사해요
      • 잘있어요

      티스토리툴바