파이썬은 함수와 클래스를 효율적으로 사용하기 위해 다양한 기법을 제공합니다. 이 중에서 데코레이터와 제너레이터는 특히 유용한 도구들입니다. 이 글에서는 파이썬 데코레이터와 제너레이터를 사용하여 함수를 효율적으로 사용하는 방법을 설명하겠습니다.
1. 파이썬 데코레이터의 개념
1.1 데코레이터의 정의
데코레이터는 함수를 다른 함수로 감싸서 함수의 동작을 변경하거나 확장하는 기법입니다. 데코레이터를 사용하면 함수의 실행 전후에 특정 동작을 수행할 수 있습니다. 데코레이터는 함수를 감싸는 역할을 하기 때문에 함수의 원래 동작을 유지하면서도 추가적인 기능을 제공할 수 있습니다.
1.2 데코레이터의 예시
데코레이터를 사용하는 가장 간단한 예시는 함수의 실행 시간을 측정하는 것입니다. 다음과 같이 데코레이터를 정의하고 사용할 수 있습니다:
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} executed in {end_time - start_time} seconds")
return result
return wrapper
@timer_decorator
def example_function():
time.sleep(1) # Simulate some work
example_function()
이 예시에서 timer_decorator
는 example_function
을 감싸서 실행 시간을 측정합니다. @timer_decorator
를 사용하여 example_function
을 데코레이팅하면, example_function
의 실행 시간이 자동으로 측정됩니다.
1.3 데코레이터의 활용
데코레이터는 다양한 상황에서 유용합니다. 예를 들어, 로깅을 위한 데코레이터를 만들면 로그를 자동으로 기록할 수 있습니다. 다음과 같이 로깅 데코레이터를 정의할 수 있습니다:
import logging
logging.basicConfig(level=logging.INFO)
def logging_decorator(func):
def wrapper(*args, **kwargs):
logging.info(f"Calling function {func.__name__} with arguments {args} and keyword arguments {kwargs}")
result = func(*args, **kwargs)
logging.info(f"Function {func.__name__} returned {result}")
return result
return wrapper
@logging_decorator
def example_function(name, age):
return f"Hello, {name} You are {age} years old."
print(example_function("Alice", 30))
이 예시에서 logging_decorator
는 example_function
을 감싸서 로그를 기록합니다. @logging_decorator
를 사용하여 example_function
을 데코레이팅하면, example_function
의 호출과 반환 값이 자동으로 로그에 기록됩니다.
2. 파이썬 제너레이터의 개념
2.1 제너레이터의 정의
제너레이터는 함수를 정의할 때 yield
키워드를 사용하여 함수가 값을 반환할 때마다 중간에 멈추고 다음에 값을 반환할 때 다시 시작할 수 있는 함수입니다. 제너레이터는 함수를 호출할 때마다 값을 한 번에 하나씩 반환하므로, 메모리 사용량을 줄일 수 있습니다.
2.2 제너레이터의 예시
제너레이터를 사용하는 가장 간단한 예시는 숫자 시퀀스를 생성하는 것입니다. 다음과 같이 제너레이터를 정의할 수 있습니다:
def infinite_sequence():
num = 0
while True:
yield num
num += 1
sequence = infinite_sequence()
for _ in range(10):
print(next(sequence))
이 예시에서 infinite_sequence
는 숫자 시퀀스를 생성하는 제너레이터입니다. next(sequence)
를 사용하여 시퀀스의 다음 값을 가져올 수 있습니다.
2.3 제너레이터의 활용
제너레이터는 다양한 상황에서 유용합니다. 예를 들어, 큰 데이터 집합을 처리할 때 제너레이터를 사용하면 메모리 사용량을 줄일 수 있습니다. 다음과 같이 제너레이터를 사용하여 큰 데이터 집합을 처리할 수 있습니다:
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('large_data.txt'):
print(line)
이 예시에서 read_large_file
는 큰 파일을 읽는 제너레이터입니다. for
루프를 사용하여 파일의 각 줄을 처리할 수 있습니다.
3. 데코레이터와 제너레이터를 함께 사용하는 방법
데코레이터와 제너레이터를 함께 사용하면 함수의 동작을 더 효율적으로 관리할 수 있습니다. 예를 들어, 데코레이터를 사용하여 제너레이터의 동작을 기록할 수 있습니다:
import time
import logging
logging.basicConfig(level=logging.INFO)
def logging_decorator(func):
def wrapper(*args, **kwargs):
logging.info(f"Calling function {func.__name__} with arguments {args} and keyword arguments {kwargs}")
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
logging.info(f"Function {func.__name__} returned {result} in {end_time - start_time} seconds")
return result
return wrapper
def infinite_sequence():
num = 0
while True:
yield num
num += 1
sequence = infinite_sequence()
for _ in range(10):
print(next(sequence))
# 데코레이터를 사용하여 제너레이터의 동작을 기록
@logging_decorator
def infinite_sequence():
num = 0
while True:
yield num
num += 1
sequence = infinite_sequence()
for _ in range(10):
print(next(sequence))
이 예시에서 logging_decorator
를 사용하여 infinite_sequence
의 동작을 기록합니다. @logging_decorator
를 사용하여 infinite_sequence
을 데코레이팅하면, infinite_sequence
의 호출과 반환 값이 자동으로 로그에 기록됩니다.
파이썬 데코레이터와 제너레이터는 함수를 효율적으로 사용하는 데 매우 유용한 도구들입니다. 데코레이터를 사용하면 함수의 동작을 변경하거나 확장할 수 있으며, 제너레이터를 사용하면 함수가 값을 한 번에 하나씩 반환할 수 있습니다. 데코레이터와 제너레이터를 함께 사용하면 함수의 동작을 더 효율적으로 관리할 수 있습니다. 이러한 기법을 사용하여 함수를 더 효율적으로 사용할 수 있습니다.
'[개발] 파이썬' 카테고리의 다른 글
6.3. 파이썬 메타 프로그래밍 (4) | 2024.12.27 |
---|---|
6.2. 파이썬 이터레이터와 컨텍스트 매니저 (0) | 2024.12.27 |
5.3. 파이썬 고급 알고리즘 (0) | 2024.12.27 |
5.2. 파이썬 알고리즘 기초 (0) | 2024.12.27 |
5.1. 기본 자료구조 활용 (0) | 2024.12.27 |