Decorators: Functies Uitbreiden
Decorators zijn een van de meest krachtige features van Python. Ze stellen je in staat om functies te modificeren zonder de originele code te veranderen.
Basis Decorator Voorbeeld:
def timer_decorator(func):
import time
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} duurde {end_time - start_time:.4f} seconden")
return result
return wrapper
@timer_decorator
def slow_function():
time.sleep(1)
return "Klaar!"
# Gebruik
slow_function() # Output: slow_function duurde 1.0012 seconden
Decorator met Parameters:
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hallo, {name}!")
greet("Python") # Print 3 keer
Context Managers: Bronnen Beheren
Context managers zorgen ervoor dat bronnen correct worden geopend en gesloten, ook bij fouten.
Aangepaste Context Manager:
from contextlib import contextmanager
@contextmanager
def database_connection():
print("Database verbinding openen...")
connection = "fake_connection"
try:
yield connection
finally:
print("Database verbinding sluiten...")
# Gebruik
with database_connection() as conn:
print(f"Werken met {conn}")
# Automatisch gesloten, ook bij fouten
Class-based Context Manager:
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
print(f"Bestand {self.filename} openen")
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"Bestand {self.filename} sluiten")
if self.file:
self.file.close()
# Gebruik
with FileManager("test.txt", "w") as f:
f.write("Test inhoud")
Generators: Geheugen Efficiënt
Generators produceren waarden on-demand, wat geheugen bespaart bij grote datasets.
Generator Functie:
def fibonacci_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
# Gebruik
for num in fibonacci_generator(10):
print(num) # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
Generator Expressie:
# Generator expressie voor kwadraten
squares = (x**2 for x in range(1000000))
# Gebruikt geen geheugen tot je het nodig hebt
first_few = [next(squares) for _ in range(5)]
print(first_few) # [0, 1, 4, 9, 16]
Metaclasses: Classes van Classes
Metaclasses geven je controle over hoe classes worden gemaakt. Een geavanceerd maar krachtig concept.
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Database(metaclass=SingletonMeta):
def __init__(self):
self.connection = "Database verbinding"
# Gebruik
db1 = Database()
db2 = Database()
print(db1 is db2) # True - zelfde instantie
Descriptors: Attribuut Toegang Controleren
Descriptors geven je controle over hoe attributen worden toegankelijk gemaakt.
class ValidatedAttribute:
def __init__(self, name, validator):
self.name = name
self.validator = validator
def __get__(self, obj, objtype=None):
if obj is None:
return self
return obj.__dict__.get(self.name)
def __set__(self, obj, value):
if not self.validator(value):
raise ValueError(f"Ongeldige waarde voor {self.name}")
obj.__dict__[self.name] = value
class Person:
age = ValidatedAttribute('age', lambda x: isinstance(x, int) and x >= 0)
def __init__(self, age):
self.age = age
# Gebruik
person = Person(25)
person.age = 30 # OK
# person.age = -5 # Raises ValueError
Async/Await: Asynchrone Programmering
Async/await maakt het mogelijk om non-blocking code te schrijven voor I/O operaties.
import asyncio
import aiohttp
async def fetch_data(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'https://httpbin.org/delay/1',
'https://httpbin.org/delay/2',
'https://httpbin.org/delay/3'
]
async with aiohttp.ClientSession() as session:
tasks = [fetch_data(session, url) for url in urls]
results = await asyncio.gather(*tasks)
print(f"Alle {len(results)} requests voltooid")
# Gebruik
asyncio.run(main())
Type Hints: Code Documentatie
Type hints maken je code zelf-documenterend en helpen bij het vinden van bugs.
from typing import List, Dict, Optional, Union, Callable
def process_data(
data: List[Dict[str, Union[str, int]]],
filter_func: Callable[[Dict], bool]
) -> Optional[List[Dict[str, Union[str, int]]]]:
"""
Verwerk een lijst van dictionaries met een filter functie.
Args:
data: Lijst van dictionaries met string/int waarden
filter_func: Functie die bepaalt welke items te behouden
Returns:
Gefilterde lijst of None als leeg
"""
filtered = [item for item in data if filter_func(item)]
return filtered if filtered else None
# Gebruik
data = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35}
]
adults = process_data(data, lambda x: x["age"] >= 30)
print(adults)
Performance Optimalisatie
Profiling met cProfile:
import cProfile
import pstats
def slow_function():
return sum(i**2 for i in range(10000))
def fast_function():
return sum(i*i for i in range(10000))
# Profile code
cProfile.run('slow_function()', 'profile_stats')
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats(10)
Gebruik van __slots__ voor geheugen efficiëntie:
class RegularClass:
def __init__(self, x, y):
self.x = x
self.y = y
class OptimizedClass:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
# OptimizedClass gebruikt minder geheugen
import sys
regular = RegularClass(1, 2)
optimized = OptimizedClass(1, 2)
print(f"Regular: {sys.getsizeof(regular.__dict__)} bytes")
print(f"Optimized: {sys.getsizeof(optimized)} bytes")
Conclusie
Deze geavanceerde technieken kunnen je Python code naar een hoger niveau tillen. Ze helpen je om:
- Efficiëntere en elegantere code te schrijven
- Betere foutafhandeling te implementeren
- Code te schrijven die schaalbaar is
- Professionele Python applicaties te bouwen
Wil je deze technieken in de praktijk leren? Bekijk onze gevorderde Python cursus voor hands-on training!