> 백엔드 개발 > 파이썬 튜토리얼 > 고급 Python 데코레이터: 코드 향상

고급 Python 데코레이터: 코드 향상

Patricia Arquette
풀어 주다: 2025-01-06 03:42:48
원래의
952명이 탐색했습니다.

Advanced Python Decorators: Elevating Your Code

당신이 분주한 주방의 셰프라고 상상해 보세요. 당신은 레시피, 즉 기능을 갖고 있습니다. 시간이 지남에 따라 대부분의 요리에는 서빙되기 전에 올리브 오일 약간, 소금 한 꼬집, 허브 뿌려야 한다는 것을 알게 됩니다. 모든 요리에 이러한 마무리 손질을 수동으로 추가하는 대신 자동으로 마무리 작업을 수행하는 보조자가 있으면 편리하지 않을까요? 이것이 바로 Python 데코레이터가 코드에 대해 수행할 수 있는 작업입니다. 우아하고 재사용 가능하며 표현력이 풍부한 방식으로 기능을 추가하는 것입니다.

이 기사에서는 고급 Python 데코레이터의 세계를 살펴보겠습니다. 우리는 기본을 넘어 매개변수화된 데코레이터, 스택 가능한 데코레이터, 심지어 클래스가 있는 데코레이터까지 자세히 살펴보겠습니다. 또한 피해야 할 모범 사례와 함정도 강조하겠습니다. 준비가 된? 요리를 시작해보세요!

기본 사항 재검토

깊이 들어가기 전에 기초부터 다시 살펴보겠습니다. Python의 데코레이터는 단순히 다른 함수(또는 메서드)를 인수로 가져와 이를 확장하고 새 함수를 반환하는 함수입니다. 예는 다음과 같습니다.

# Basic decorator example
def simple_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}...")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished.")
        return result
    return wrapper

@simple_decorator
def say_hello():
    print("Hello, world!")

say_hello()
로그인 후 복사
로그인 후 복사

출력:

Calling say_hello...
Hello, world!
say_hello finished.
로그인 후 복사
로그인 후 복사

이제 고급 사용 사례를 살펴보겠습니다.

매개변수화된 데코레이터

때때로 데코레이터는 자신의 주장을 받아들여야 합니다. 예를 들어, 다양한 수준(INFO, DEBUG, ERROR)에서 메시지를 기록하는 데코레이터를 원한다면 어떻게 해야 할까요?

# Parameterized decorator example
def log(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"[{level}] Calling {func.__name__}...")
            result = func(*args, **kwargs)
            print(f"[{level}] {func.__name__} finished.")
            return result
        return wrapper
    return decorator

@log("INFO")
def process_data():
    print("Processing data...")

process_data()
로그인 후 복사

출력:

[INFO] Calling process_data...
Processing data...
[INFO] process_data finished.
로그인 후 복사

데코레이터를 반환하는 함수인 이 계층 구조는 유연하고 매개변수화된 데코레이터를 만드는 데 핵심입니다.

쌓을 수 있는 데코레이터

Python을 사용하면 단일 함수에 여러 데코레이터를 적용할 수 있습니다. 두 개의 데코레이터를 생성하여 쌓아보겠습니다.

# Stackable decorators

def uppercase(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

def exclaim(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!!!"
    return wrapper

@uppercase
@exclaim
def greet():
    return "hello"

print(greet())
로그인 후 복사

출력:

HELLO!!!
로그인 후 복사

여기서 데코레이터는 상향식 방식으로 적용됩니다. @exclaim은 Greeting을 래핑하고 @uppercase는 결과를 래핑합니다.

클래스를 데코레이터로 사용

파이썬의 덜 알려진 기능은 클래스를 데코레이터로 사용할 수 있다는 것입니다. 이는 상태를 유지해야 할 때 특히 유용할 수 있습니다.

# Class-based decorator
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.call_count = 0

    def __call__(self, *args, **kwargs):
        self.call_count += 1
        print(f"Call {self.call_count} to {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

say_hello()
say_hello()
로그인 후 복사

출력:

Call 1 to say_hello
Hello!
Call 2 to say_hello
Hello!
로그인 후 복사

여기서 call 메소드를 사용하면 클래스가 함수처럼 동작하여 대상 함수를 원활하게 래핑할 수 있습니다.

메소드 데코레이터

데코레이터는 클래스의 메서드와 마찬가지로 잘 작동합니다. 하지만 올바른 자기관리는 필수입니다.

# Method decorator example
def log_method(func):
    def wrapper(self, *args, **kwargs):
        print(f"Method {func.__name__} called on {self}")
        return func(self, *args, **kwargs)
    return wrapper

class Greeter:
    @log_method
    def greet(self, name):
        print(f"Hello, {name}!")

obj = Greeter()
obj.greet("Alice")
로그인 후 복사

출력:

Method greet called on <__main__.Greeter object at 0x...>
Hello, Alice!
로그인 후 복사

데코레이터와 컨텍스트 관리자 결합

가끔 데코레이터를 리소스 관리와 통합해야 할 때도 있습니다. 예를 들어, 함수 실행 시간을 측정하는 데코레이터를 만들어 보겠습니다.

import time

# Timing decorator
def time_it(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f} seconds")
        return result
    return wrapper

@time_it
def slow_function():
    time.sleep(2)
    print("Done sleeping!")

slow_function()
로그인 후 복사

출력:

# Basic decorator example
def simple_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}...")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished.")
        return result
    return wrapper

@simple_decorator
def say_hello():
    print("Hello, world!")

say_hello()
로그인 후 복사
로그인 후 복사

모범 사례

데코레이터와 작업할 때는 가독성과 유지 관리 가능성을 염두에 두는 것이 중요합니다. 다음은 몇 가지 팁입니다.

  • functools.wraps 사용: 이렇게 하면 원래 함수의 메타데이터가 보존됩니다.
Calling say_hello...
Hello, world!
say_hello finished.
로그인 후 복사
로그인 후 복사
  • 철저한 테스트: 데코레이터는 특히 여러 데코레이터를 연결할 때 미묘한 버그를 유발할 수 있습니다.

  • 문서 데코레이터: 각 데코레이터가 수행하는 작업과 예상 매개변수를 명확하게 문서화합니다.

  • 과용 방지: 데코레이터는 강력하지만 지나치게 사용하면 코드를 따라가기가 어려워질 수 있습니다.

마무리

데코레이터는 Python의 가장 표현력이 풍부한 기능 중 하나입니다. 이를 통해 깨끗하고 재사용 가능한 방식으로 동작을 확장하고 수정할 수 있습니다. 매개변수화된 데코레이터부터 클래스 기반 구현까지 가능성은 무궁무진합니다. 기술을 연마하면서 데코레이터를 활용하여 더 깔끔하고 Python적인 코드를 작성하게 될 것이며 아마도 훌륭한 요리사처럼 자신이 만드는 모든 레시피에 시그니처 터치를 추가하게 될 것입니다.

참고: AI 지원 콘텐츠

위 내용은 고급 Python 데코레이터: 코드 향상의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿