Python Decorators and Generators: Advanced Patterns
Decorators with Arguments
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(n=3)
def greet(name):
print(f"Hello, {name}!")
Class-based Decorators
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"Call {self.count} of {self.func.__name__}")
return self.func(*args, **kwargs)
Generator Pipelines
Generators are memory-efficient because they yield items lazily:
def read_large_file(file_path):
with open(file_path) as f:
for line in f:
yield line.strip()
def filter_lines(lines, keyword):
for line in lines:
if keyword in line:
yield line
pipeline = filter_lines(read_large_file("data.log"), "ERROR")
for err in pipeline:
print(err) # Processes one line at a time in memory