Post

파이썬 고급 문법: 데코레이터와 제너레이터

데코레이터와 제너레이터의 개념과 활용 방법

파이썬은 효율적이고 가독성 높은 코드를 작성할 수 있는 고급 기능을 제공합니다. 데코레이터(Decorator)제너레이터(Generator)는 이러한 기능 중 두 가지로, 각각 함수 확장과 효율적인 데이터 처리를 가능하게 합니다. 이번 글에서는 이 두 가지 개념과 활용 방법을 살펴보겠습니다.

1. 데코레이터란?

데코레이터는 함수나 메서드의 동작을 확장하거나 수정할 수 있는 함수입니다. 다른 함수를 감싸서 새로운 기능을 추가하는 데 사용됩니다.

2. 데코레이터의 기본 구조

기본 구조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def decorator(func):
    def wrapper(*args, **kwargs):
        print("기능 추가 전")
        result = func(*args, **kwargs)
        print("기능 추가 후")
        return result
    return wrapper

@decorator
def say_hello():
    print("Hello, World!")

say_hello()
# 출력:
# 기능 추가 전
# Hello, World!
# 기능 추가 후

3. 데코레이터 활용

1) 실행 시간 측정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time

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

@timer
def long_task():
    time.sleep(2)
    print("작업 완료!")

long_task()
# 출력:
# 작업 완료!
# 실행 시간: 2.0001초

2) 인증 시스템

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def require_auth(func):
    def wrapper(user_authenticated, *args, **kwargs):
        if not user_authenticated:
            print("인증이 필요합니다!")
            return
        return func(*args, **kwargs)
    return wrapper

@require_auth
def access_secure_area(user_authenticated):
    print("보안 구역에 접근했습니다.")

access_secure_area(False)  # 출력: 인증이 필요합니다!
access_secure_area(True)   # 출력: 보안 구역에 접근했습니다.

3) 다중 데코레이터

  • 여러 데코레이터를 동시에 사용할 수 있습니다. 위에서부터 아래로 실행됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def decorator_one(func):
    def wrapper(*args, **kwargs):
        print("Decorator One")
        return func(*args, **kwargs)
    return wrapper

def decorator_two(func):
    def wrapper(*args, **kwargs):
        print("Decorator Two")
        return func(*args, **kwargs)
    return wrapper

@decorator_one
@decorator_two
def greet():
    print("Hello!")

greet()
# 출력:
# Decorator One
# Decorator Two
# Hello!

4. 제너레이터란?

제너레이터(Generator)이터레이터를 생성하는 함수로, 데이터를 한 번에 메모리에 올리지 않고 필요한 순간에 값을 생성합니다. yield 키워드를 사용하여 데이터를 반환합니다.

5. 제너레이터의 기본 구조

기본 구조

1
2
3
4
5
6
7
8
9
10
11
def generator_function():
    yield 1
    yield 2
    yield 3

for value in generator_function():
    print(value)
# 출력:
# 1
# 2
# 3
  • yield는 값을 반환하면서 함수의 상태를 저장합니다.
  • next()를 호출하면 다음 값을 반환합니다.

예제

1
2
3
4
gen = generator_function()
print(next(gen))  # 출력: 1
print(next(gen))  # 출력: 2
print(next(gen))  # 출력: 3

6. 제너레이터의 활용

1) 대규모 데이터 처리

  • 제너레이터는 메모리를 절약하며 데이터를 처리할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

for num in count_up_to(5):
    print(num)
# 출력:
# 1
# 2
# 3
# 4
# 5

2) 무한 데이터 스트림

  • 제너레이터를 사용하면 무한 데이터 스트림을 쉽게 처리할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1

gen = infinite_sequence()
print(next(gen))  # 출력: 0
print(next(gen))  # 출력: 1
print(next(gen))  # 출력: 2

3) 제너레이터 표현식

  • 리스트 컴프리헨션과 유사하지만, 메모리 효율이 높습니다.
1
2
3
4
5
6
7
8
9
gen = (x ** 2 for x in range(5))
for value in gen:
    print(value)
# 출력:
# 0
# 1
# 4
# 9
# 16

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

데코레이터와 제너레이터를 함께 사용하면 더욱 강력한 기능을 구현할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def generator_decorator(func):
    def wrapper(*args, **kwargs):
        gen = func(*args, **kwargs)
        for value in gen:
            yield value ** 2
    return wrapper

@generator_decorator
def numbers():
    for i in range(5):
        yield i

for value in numbers():
    print(value)
# 출력:
# 0
# 1
# 4
# 9
# 16

정리

  • 데코레이터: 함수의 동작을 확장하고 반복 코드를 줄이는 강력한 도구.
  • 제너레이터: 데이터를 한 번에 메모리에 올리지 않고, 필요한 순간에 생성하는 효율적인 함수.
  • 두 기능을 조합하여 강력하고 효율적인 프로그램을 작성할 수 있습니다.

다음 글 예고:
파이썬의 심화 주제로, “컨텍스트 매니저”를 배워보겠습니다!

This post is licensed under CC BY 4.0 by the author.