Python/Python 심화

Python 데코레이터와 제너레이터

임베디드 친구 2025. 7. 18. 19:54
728x90
반응형

Python 데코레이터와 제너레이터

Python은 간결하고 강력한 문법으로 초보자부터 전문가까지 폭넓게 사용되는 언어입니다. 특히 Python의 고급 기능인 데코레이터제너레이터는 코드의 재사용성을 높이고, 효율적인 프로그램을 작성할 수 있도록 도와줍니다. 이번 포스팅에서는 데코레이터와 제너레이터의 기본 개념부터 실용적인 예제까지 살펴보겠습니다.

데코레이터 (Decorator)

데코레이터는 함수를 감싸서 새로운 기능을 추가하거나 동작을 수정하는 데 사용되는 고급 Python 기능입니다. 주로 코드를 더 간결하고 명확하게 만드는 데 유용합니다.

데코레이터의 기본 구조

데코레이터는 함수나 클래스에 적용될 수 있으며, 일반적으로 다음과 같은 구조로 작성됩니다:

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        print(f"{original_function.__name__} 함수가 호출되기 전입니다.")
        result = original_function(*args, **kwargs)
        print(f"{original_function.__name__} 함수가 호출된 후입니다.")
        return result
    return wrapper_function

이를 적용하려면 데코레이터를 @decorator_name 형식으로 지정합니다:

@decorator_function
def display():
    print("display 함수가 실행됩니다.")

# 호출
display()

출력:

display 함수가 호출되기 전입니다.
display 함수가 실행됩니다.
display 함수가 호출된 후입니다.

데코레이터의 실용적인 예제

1. 실행 시간 측정 데코레이터

프로그램의 성능을 측정하고 싶을 때 유용한 데코레이터입니다.

import time

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 함수 실행 시간: {end_time - start_time:.4f}초")
        return result
    return wrapper

@timer_decorator
def compute_factorial(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

# 호출
print(compute_factorial(10))

2. 사용자 인증 데코레이터

특정 함수에 접근하기 전에 사용자 권한을 확인하는 데코레이터입니다.

def requires_auth(func):
    def wrapper(user, *args, **kwargs):
        if not user.get("is_authenticated", False):
            print("인증이 필요합니다.")
            return
        return func(user, *args, **kwargs)
    return wrapper

@requires_auth
def view_profile(user):
    print(f"{user['username']}의 프로필을 보여줍니다.")

# 호출
user1 = {"username": "test_user", "is_authenticated": True}
user2 = {"username": "guest", "is_authenticated": False}

view_profile(user1)  # 인증됨
view_profile(user2)  # 인증되지 않음

제너레이터 (Generator)

제너레이터는 Python에서 반복 가능한(iterable) 객체를 생성하는 특별한 함수입니다. 제너레이터는 yield 키워드를 사용하여 데이터를 하나씩 반환합니다. 메모리를 효율적으로 사용하면서 대량의 데이터를 처리할 수 있습니다.

제너레이터의 기본 구조

def simple_generator():
    yield 1
    yield 2
    yield 3

# 호출
for value in simple_generator():
    print(value)

출력:

1
2
3

제너레이터 표현식

리스트 컴프리헨션과 유사하게, Python은 제너레이터 표현식도 제공합니다.

gen_exp = (x * x for x in range(5))
for value in gen_exp:
    print(value)

출력:

0
1
4
9
16

제너레이터의 실용적인 예제

1. 큰 데이터 처리

메모리를 효율적으로 사용하여 대량 데이터를 처리하는 데 적합합니다.

def fibonacci(limit):
    a, b = 0, 1
    while a < limit:
        yield a
        a, b = b, a + b

# 호출
for number in fibonacci(100):
    print(number)

2. 파일 읽기 처리

대용량 파일을 한 줄씩 읽는 데 유용합니다.

def read_large_file(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            yield line.strip()

# 호출
for line in read_large_file('example.txt'):
    print(line)

데코레이터와 제너레이터의 결합

데코레이터와 제너레이터를 결합하여 강력한 기능을 구현할 수도 있습니다. 예를 들어, 특정 조건에서만 데이터를 처리하는 로직을 만들 수 있습니다.

def filter_decorator(predicate):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for value in func(*args, **kwargs):
                if predicate(value):
                    yield value
        return wrapper
    return decorator

@filter_decorator(lambda x: x % 2 == 0)
def generate_numbers(limit):
    for i in range(limit):
        yield i

# 호출
for even_number in generate_numbers(10):
    print(even_number)

출력:

0
2
4
6
8

정리

데코레이터와 제너레이터는 Python의 고급 기능 중에서도 매우 강력한 도구입니다. 데코레이터는 코드를 간결하게 유지하면서 기능을 확장할 수 있게 하고, 제너레이터는 메모리 사용을 최소화하면서 효율적으로 데이터를 처리할 수 있게 합니다. 이번 포스팅에서 다룬 개념과 예제를 바탕으로 여러분의 프로젝트에서 이 기능들을 활용해보세요!

728x90
반응형