Functies Maken in Python: Complete Gids voor Beginners
Leer hoe je professionele functies maakt in Python. Van basis syntax tot geavanceerde technieken met praktische voorbeelden voor data engineers.
Zoek je Python developers?
Vind gespecialiseerde Data Engineers en Python developers voor je data projecten
Inhoudsopgave
1. Wat zijn functies en waarom gebruiken?
Definitie
Een functie in Python is een herbruikbaar blok code dat een specifieke taak uitvoert. Functies helpen je code te organiseren, te hergebruiken en leesbaar te maken.
Herbruikbaarheid
Schrijf code één keer en gebruik het meerdere keren
Modulariteit
Breek complexe problemen op in kleine, beheersbare delen
Leesbaarheid
Beschrijvende functienamen maken code begrijpelijk
Debuggen
Makkelijk testen en debuggen van geïsoleerde code
Wanneer gebruik je functies?
- DRY principe: Don't Repeat Yourself - vermijd code duplicatie
- Complexe logica: Breek grote taken op in kleinere functies
- Team samenwerking: Duidelijke functie interfaces voor teamwerk
- Testing: Unit testing is makkelijker met functies
- Onderhoud: Updates op één plaats in plaats van overal
Team nodig voor Python projecten?
Vind ervaren Python developers gespecialiseerd in data engineering en analytics
2. Basis syntax: Je eerste functie
Stap 1: Een simpele functie maken
def groet_gebruiker():
"""Deze functie groet de gebruiker"""
print("Hallo! Welkom bij DataPartner365")
# De functie aanroepen
groet_gebruiker() # Output: Hallo! Welkom bij DataPartner365
Uitleg: def definieert een nieuwe functie. De functienaam moet beschrijvend zijn en volgt Python conventies (snake_case).
Stap 2: Functie met parameters
def persoonlijke_groet(naam):
"""Groet een specifieke persoon"""
print(f"Hallo {naam}! Welkom terug.")
# De functie aanroepen met een argument
persoonlijke_groet("Jan") # Output: Hallo Jan! Welkom terug.
persoonlijke_groet("Sandra") # Output: Hallo Sandra! Welkom terug.
Uitleg: Parameters zijn variabelen die je tussen de haakjes zet. Arguments zijn de waarden die je meegeeft bij het aanroepen.
Stap 3: Meerdere parameters
def bereken_totaal(prijs, aantal, btw_percentage=21):
"""Bereken totaal bedrag inclusief BTW"""
subtotaal = prijs * aantal
btw_bedrag = subtotaal * (btw_percentage / 100)
totaal = subtotaal + btw_bedrag
return totaal
# Verschillende manieren om de functie aan te roepen
totaal1 = bereken_totaal(10, 3) # Gebruikt standaard BTW 21%
totaal2 = bereken_totaal(10, 3, 9) # Specificeer BTW 9%
totaal3 = bereken_totaal(btw_percentage=9, aantal=3, prijs=10) # Keyword arguments
print(f"Totaal 1: €{totaal1:.2f}") # Output: Totaal 1: €36.30
print(f"Totaal 2: €{totaal2:.2f}") # Output: Totaal 2: €32.70
Uitleg: Default parameters hebben een standaardwaarde. Keyword arguments maken code leesbaarder.
3. Parameters en arguments uitgebreid
Positional Arguments
Volgorde is belangrijk, worden op positie doorgegeven
def vermenigvuldig(a, b):
return a * b
result = vermenigvuldig(3, 4) # a=3, b=4
Keyword Arguments
Expliciet benoemen, volgorde maakt niet uit
def vermenigvuldig(a, b):
return a * b
result = vermenigvuldig(b=4, a=3)
Default Parameters
Standaardwaarden voor optionele parameters
def groet(naam="Gast"):
return f"Hallo {naam}!"
groet() # "Hallo Gast!"
groet("Jan") # "Hallo Jan!"
*args en **kwargs
Variabele aantal arguments
def som(*args):
return sum(args)
som(1, 2, 3, 4) # 10
Complete voorbeeld: Alle parameter types
def data_verwerk_functie(verplicht, *args, standaard="default", **kwargs):
"""
Voorbeeld met alle parameter types:
- verplicht: positional required
- *args: variabele positional arguments
- standaard: default parameter
- **kwargs: variabele keyword arguments
"""
print(f"Verplicht: {verplicht}")
print(f"Args: {args}")
print(f"Standaard: {standaard}")
print(f"Kwargs: {kwargs}")
# Return een dictionary met alle data
return {
"verplicht": verplicht,
"args": args,
"standaard": standaard,
"kwargs": kwargs
}
# Voorbeeld aanroep
resultaat = data_verwerk_functie(
"verplichte_waarde", # positional
"extra1", "extra2", # *args
standaard="aangepast", # keyword
extra_optie="waarde", # **kwargs
nog_een_optie=123
)
print(resultaat)
Klaar voor Python projecten?
Vind de juiste experts of plaats je Python Developer vacature
4. Return waarden en meerdere returns
Return vs Print
Print toont output op het scherm, maar return geeft een waarde terug die je kunt opslaan in een variabele of verder verwerken.
Enkele return waarde
def bereken_kwadraat(getal):
return getal ** 2
resultaat = bereken_kwadraat(5)
print(resultaat) # 25
print(bereken_kwadraat(3) + bereken_kwadraat(4)) # 9 + 16 = 25
Meerdere return waarden (tuple)
def bereken_statistieken(getallen):
"""Bereken gemiddelde en standaarddeviatie"""
gemiddelde = sum(getallen) / len(getallen)
variantie = sum((x - gemiddelde) ** 2 for x in getallen) / len(getallen)
std_dev = variantie ** 0.5
return gemiddelde, std_dev # Retourneert een tuple
# Functie aanroepen en resultaten uitpakken
data = [1, 2, 3, 4, 5]
gem, std = bereken_statistieken(data)
print(f"Gemiddelde: {gem:.2f}") # 3.00
print(f"Standaarddeviatie: {std:.2f}") # 1.41
# Of als tuple ontvangen
resultaat = bereken_statistieken(data)
print(resultaat) # (3.0, 1.4142135623730951)
Return met dictionary
def analyseer_dataset(data):
"""Complete dataset analyse"""
analyses = {
"aantal": len(data),
"som": sum(data),
"gemiddelde": sum(data) / len(data),
"minimum": min(data),
"maximum": max(data),
"unieke_waarden": len(set(data))
}
return analyses
data = [10, 20, 30, 20, 40, 10]
resultaat = analyseer_dataset(data)
for key, value in resultaat.items():
print(f"{key}: {value}")
5. Scope van variabelen
| Scope Type | Waar gedefinieerd | Toegankelijk in | Voorbeeld |
|---|---|---|---|
| Local | Binnen een functie | Alleen binnen die functie | def func(): x = 10 |
| Enclosing | Binnen outer functie | Binnen nested functies | def outer(): x=10; def inner(): print(x) |
| Global | Buiten alle functies | Overal in het bestand | x = 10; def func(): print(x) |
| Built-in | Python zelf | Overal | print(), len(), sum() |
Scope voorbeeld
# Global variabele
global_var = "Ik ben global"
def voorbeeld_functie():
# Local variabele
local_var = "Ik ben local"
def nested_functie():
# Nested local variabele
nested_var = "Ik ben nested"
print(local_var) # Werkt: enclosing scope
print(global_var) # Werkt: global scope
nested_functie()
# print(nested_var) # Error: nested_var niet beschikbaar hier
voorbeeld_functie()
# print(local_var) # Error: local_var niet beschikbaar hier
print(global_var) # Werkt: global scope
6. Geavanceerde functie technieken
Lambda Functies
Anonieme functies voor eenvoudige operaties
# Traditionele functie
def kwadraat(x):
return x ** 2
# Lambda equivalent
kwadraat = lambda x: x ** 2
# Gebruik met map()
getallen = [1, 2, 3, 4, 5]
kwadraten = list(map(lambda x: x ** 2, getallen))
# Resultaat: [1, 4, 9, 16, 25]
Nested Functies
Functies binnen functies voor encapsulation
def data_validator(dataset):
"""Valideer dataset met nested helper functies"""
def is_numeric(value):
return isinstance(value, (int, float))
def is_positive(value):
return value > 0
valid_data = []
for item in dataset:
if is_numeric(item) and is_positive(item):
valid_data.append(item)
return valid_data
Decorators
Functies die andere functies aanpassen
def timer_decorator(func):
"""Meet hoe lang een functie duurt"""
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
@timer_decorator
def zware_berekening():
import time
time.sleep(2)
return "Klaar"
zware_berekening()
Generator Functies
Yield i.p.v. return voor memory efficiency
def fibonacci_generator(limit):
"""Genereer Fibonacci reeks"""
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
# Gebruik
for num in fibonacci_generator(100):
print(num) # Print 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
7. Praktijkvoorbeelden voor data engineers
Data Cleaning Functie
def clean_dataframe(df, missing_strategy='mean', outlier_threshold=3):
"""
Clean een pandas DataFrame met verschillende strategieën
Parameters:
- df: pandas DataFrame
- missing_strategy: 'mean', 'median', 'drop', of 'fill'
- outlier_threshold: standaard deviaties voor outlier detection
"""
import pandas as pd
import numpy as np
# Maak een kopie om het origineel niet te wijzigen
df_clean = df.copy()
# 1. Handle missing values
if missing_strategy == 'mean':
df_clean = df_clean.fillna(df_clean.mean())
elif missing_strategy == 'median':
df_clean = df_clean.fillna(df_clean.median())
elif missing_strategy == 'drop':
df_clean = df_clean.dropna()
# 2. Remove outliers
for column in df_clean.select_dtypes(include=[np.number]).columns:
mean = df_clean[column].mean()
std = df_clean[column].std()
lower_bound = mean - outlier_threshold * std
upper_bound = mean + outlier_threshold * std
df_clean = df_clean[(df_clean[column] >= lower_bound) &
(df_clean[column] <= upper_bound)]
# 3. Normalize numeric columns
numeric_cols = df_clean.select_dtypes(include=[np.number]).columns
df_clean[numeric_cols] = (df_clean[numeric_cols] - df_clean[numeric_cols].mean()) / df_clean[numeric_cols].std()
return df_clean
# Gebruik:
# cleaned_df = clean_dataframe(raw_df, missing_strategy='median', outlier_threshold=2.5)
ETL Pipeline Functie
def etl_pipeline(bron_path, bestemming_path, transformaties=None):
"""
Complete ETL pipeline voor data processing
Parameters:
- bron_path: pad naar bron data
- bestemming_path: pad voor opgeslagen data
- transformaties: lijst van transformatie functies
"""
import pandas as pd
import json
# 1. Extract - data inlezen
def extract(path):
if path.endswith('.csv'):
return pd.read_csv(path)
elif path.endswith('.json'):
return pd.read_json(path)
elif path.endswith('.parquet'):
return pd.read_parquet(path)
else:
raise ValueError("Bestandsformaat niet ondersteund")
# 2. Transform - data bewerken
def transform(data, transformations):
transformed_data = data.copy()
# Standaard transformaties
default_transforms = [
lambda df: df.dropna(),
lambda df: df.drop_duplicates(),
lambda df: df.convert_dtypes()
]
# Combineer standaard en custom transformaties
all_transforms = default_transforms + (transformations or [])
for transform_func in all_transforms:
transformed_data = transform_func(transformed_data)
return transformed_data
# 3. Load - data opslaan
def load(data, path):
if path.endswith('.parquet'):
data.to_parquet(path, index=False)
elif path.endswith('.csv'):
data.to_csv(path, index=False)
else:
raise ValueError("Bestandsformaat niet ondersteund")
# Uitvoeren van de pipeline
raw_data = extract(bron_path)
processed_data = transform(raw_data, transformaties)
load(processed_data, bestemming_path)
return {
"bron_rows": len(raw_data),
"processed_rows": len(processed_data),
"bestemming": bestemming_path
}
8. Best practices en veelgemaakte fouten
bereken_maandelijkse_omzet()func1() of doe_iets()"""Bereken de omzet voor een specifieke maand."""def tel_woorden(text: str) -> int:def tel_woorden(text):def connect(host="localhost", port=5432):def connect(host, port):Veelgemaakte fouten
- Geen return statement: Vergeet niet wat je functie moet retourneren
- Side effects: Functies die globale variabelen veranderen zonder dat dit duidelijk is
- Te complex: Functies die te veel doen (meer dan 20-30 regels)
- Geen error handling: Geen try-except blokken voor foutgevoelige operaties
- Hardcoded waarden: Magische getallen in functies ipv parameters
Checklist voor professionele functies
- Beschrijvende functienaam (snake_case)
- Complete docstring met parameters en return
- Type hints voor parameters en return
- Default waarden voor optionele parameters
- Error handling met try-except
- Unit tests geschreven
- Geen globale variabele aanpassingen
- Logging voor debugging
Klaar om Python functies te gebruiken?
Vind gespecialiseerde Python developers of plaats je vacature