Nadat u de basis van Python heeft geleerd, is het tijd om uw vaardigheden naar een hoger niveau te tillen. Deze geavanceerde technieken zullen u helpen om elegantere, efficiëntere en meer Pythonische code te schrijven.
Decorators: De Kracht van Functie-modificatie
Decorators zijn een van de meest krachtige functies in Python. Ze stellen u in staat om het gedrag van functies of klassen te wijzigen zonder hun broncode te veranderen.
Basis Decorator Voorbeeld
def timing_decorator(func):
import time
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} duurde {end - start:.4f} seconden")
return result
return wrapper
@timing_decorator
def slow_function():
import time
time.sleep(1)
return "Klaar!"
# Gebruik
slow_function() # Output: slow_function duurde 1.0021 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("Maria") # Print 3 keer "Hallo, Maria!"
Generators: Efficiënt Geheugengebruik
Generators zijn functies die waarden genereren on-demand, wat geheugenefficiënt is voor 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) # Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
Generator Expressions
# Memory-efficient manier om grote datasets te verwerken
even_squares = (x**2 for x in range(1000000) if x % 2 == 0)
# Gebruik slechts geheugen wanneer nodig
for square in even_squares:
if square > 100:
break
print(square)
Context Managers: Bronbeheer
Context managers helpen bij het correct beheren van bronnen zoals bestanden, database-connecties en locks.
Custom Context Manager
class DatabaseConnection:
def __init__(self, db_name):
self.db_name = db_name
self.connection = None
def __enter__(self):
print(f"Verbinding maken met {self.db_name}")
self.connection = f"Connected to {self.db_name}"
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"Verbinding sluiten met {self.db_name}")
if exc_type:
print(f"Fout opgetreden: {exc_val}")
return False
# Gebruik
with DatabaseConnection("mijn_database") as conn:
print(f"Werken met {conn}")
# Automatisch opschonen na dit blok
Metaclasses: Klassen die Klassen Maken
Metaclasses zijn geavanceerde technieken die bepalen hoe klassen worden gecreëerd. Ze zijn krachtig maar moeten voorzichtig worden gebruikt.
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 DatabaseManager(metaclass=SingletonMeta):
def __init__(self):
self.connections = []
def add_connection(self, conn):
self.connections.append(conn)
# Gebruik
db1 = DatabaseManager()
db2 = DatabaseManager()
print(db1 is db2) # Output: True (zelfde instance)
Async/Await: Asynchrone Programmering
Asynchrone programmering stelt u in staat om I/O-bound taken efficiënt te verwerken zonder blocking.
Basis Async Functie
import asyncio
import aiohttp
async def fetch_data(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/posts/3'
]
tasks = [fetch_data(url) for url in urls]
results = await asyncio.gather(*tasks)
for i, result in enumerate(results):
print(f"Result {i+1}: {len(result)} characters")
# Uitvoeren
asyncio.run(main())
Descriptors: Attribuut Toegang Beheren
Descriptors geven u controle over hoe attributen worden toegankelijk gemaakt, ingesteld en verwijderd.
class ValidatedAttribute:
def __init__(self, min_value=0, max_value=100):
self.min_value = min_value
self.max_value = max_value
def __get__(self, obj, objtype=None):
if obj is None:
return self
return obj.__dict__.get(self.name, 0)
def __set__(self, obj, value):
if not isinstance(value, (int, float)):
raise TypeError("Waarde moet een getal zijn")
if not (self.min_value <= value <= self.max_value):
raise ValueError(f"Waarde moet tussen {self.min_value} en {self.max_value} liggen")
obj.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class Student:
grade = ValidatedAttribute(0, 100)
def __init__(self, name):
self.name = name
# Gebruik
student = Student("Jan")
student.grade = 85 # OK
# student.grade = 105 # Zou een ValueError geven
Functional Programming Technieken
Python ondersteunt functionele programmering met functies als map, filter, reduce en lambda.
Higher-Order Functions
from functools import reduce
# Map, Filter, Reduce
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Map: transformeer elke waarde
squares = list(map(lambda x: x**2, numbers))
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# Filter: selecteer waarden die voldoen aan conditie
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8, 10]
# Reduce: reduceer tot één waarde
sum_all = reduce(lambda x, y: x + y, numbers)
print(sum_all) # 55
Partial Functions
from functools import partial
def multiply(x, y):
return x * y
# Maak een gespecialiseerde versie
double = partial(multiply, 2)
triple = partial(multiply, 3)
print(double(5)) # 10
print(triple(5)) # 15
Memory Management en Optimalisatie
Begrijp hoe Python geheugen beheert en hoe u uw code kunt optimaliseren.
Slots voor Geheugenefficiëntie
class OptimizedClass:
__slots__ = ['x', 'y', 'z']
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
# Gebruikt minder geheugen dan een normale klasse
# Geen __dict__ attribute, snellere attribuuttoegang
Testing en Debugging
Geavanceerde technieken voor het testen en debuggen van uw Python code.
Property-Based Testing
from hypothesis import given, strategies as st
@given(st.integers())
def test_absolute_value(x):
assert abs(x) >= 0
assert abs(x) == abs(-x)
# Hypothesis genereert automatisch testcases
Beste Practices
- PEP 8: Volg Python's style guide
- Type Hints: Gebruik type annotations voor betere code documentatie
- Docstrings: Documenteer uw functies en klassen goed
- Error Handling: Gebruik specifieke exceptions
- Testing: Schrijf unit tests voor uw code
Conclusie
Deze geavanceerde technieken maken Python tot een krachtige taal voor complexe projecten. Door deze concepten te beheersen, kunt u elegante, efficiënte en onderhoudbare code schrijven die professionele standaarden voldoet.
Wilt u Deze Technieken Leren?
Onze gevorderde Python cursus behandelt al deze onderwerpen in detail met praktische oefeningen.
Bekijk Geavanceerde Cursussen