DataPartner365

Jouw partner voor datagedreven groei en inzichten

Functies Maken in Python: Complete Gids voor Beginners

Laatst bijgewerkt: 20 december 2025
Leestijd: 15 minuten
Python, Functies, Programming, Data Engineering, Code

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

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

Best Practice Goed Voorbeeld Slecht Voorbeeld Beschrijvende namen bereken_maandelijkse_omzet() func1() of doe_iets() Docstrings """Bereken de omzet voor een specifieke maand.""" Geen documentatie Enkele verantwoordelijkheid 1 functie = 1 taak Functie doet alles (data lezen, verwerken, opslaan) Type hints def tel_woorden(text: str) -> int: def tel_woorden(text): Default parameters def connect(host="localhost", port=5432): def connect(host, port):

Veelgemaakte fouten

  1. Geen return statement: Vergeet niet wat je functie moet retourneren
  2. Side effects: Functies die globale variabelen veranderen zonder dat dit duidelijk is
  3. Te complex: Functies die te veel doen (meer dan 20-30 regels)
  4. Geen error handling: Geen try-except blokken voor foutgevoelige operaties
  5. 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