Defining Functions in Python
Well-written functions are the backbone of clean, reusable, and maintainable data science code. In 2026, following modern Python standards for function definition helps you create modular, testable, and professional-grade data pipelines.
TL;DR — Modern Function Definition Best Practices
- Use type hints for parameters and return values
- Always include a clear docstring
- Keep functions small and focused (single responsibility)
- Use default arguments wisely
1. Modern Function Definition with Type Hints
from typing import List, Optional
import pandas as pd
from datetime import datetime
def calculate_monthly_revenue(
transactions: List[dict],
month: int,
year: int = 2026
) -> float:
"""
Calculate total revenue for a given month and year.
Args:
transactions: List of transaction dictionaries
month: Month number (1-12)
year: Year (default: current year)
Returns:
Total revenue as float
"""
total = 0.0
for tx in transactions:
tx_date = datetime.fromisoformat(tx["date"])
if tx_date.month == month and tx_date.year == year:
total += tx.get("amount", 0.0)
return round(total, 2)
2. Real-World Data Science Function Example
def clean_and_summarize_sales(
df,
min_amount: float = 0.0,
region: Optional[str] = None
) -> pd.DataFrame:
"""
Clean sales data and return summary statistics.
"""
# Filter and clean
cleaned = df[df["amount"] >= min_amount].copy()
if region:
cleaned = cleaned[cleaned["region"] == region]
# Add useful columns
cleaned = cleaned.assign(
year=cleaned["order_date"].dt.year,
month_name=cleaned["order_date"].dt.month_name()
)
# Return summary
summary = cleaned.groupby("region").agg({
"amount": ["sum", "mean", "count"],
"customer_id": "nunique"
}).round(2)
return summary
3. Best Practices for Data Science Functions in 2026
- Always add clear, informative docstrings (Google or NumPy style)
- Use type hints for all parameters and return values
- Keep functions focused on doing one thing well
- Use descriptive parameter and function names
- Provide sensible default values where appropriate
- Return clean, consistent data types
Anatomy of a Good Function
A function bundles a task under a name: def, a name, parameters, a body and a return value. Good data functions do one job, take inputs as parameters rather than reading globals, and return results instead of printing them.
Type hints and a short docstring document what goes in and what comes out. Small pure functions like these are easy to test and easy to reuse across notebooks.
Worked Example: A Reusable Cleaning Function
A function cleans a price column and is tested with a quick assertion.
import pandas as pd
def clean_prices(df: pd.DataFrame, column: str = "price") -> pd.DataFrame:
"""Return a copy with the price column as float and negatives removed."""
out = df.copy()
out[column] = pd.to_numeric(out[column], errors="coerce")
return out[out[column] >= 0]
raw = pd.DataFrame({"price": ["10.5", "-3", "abc", "7"]})
result = clean_prices(raw)
print(result)
assert result["price"].tolist() == [10.5, 7.0]
print("test passed")
The function never changes the input, because it works on a copy. Invalid text becomes NaN and is filtered out along with the negative value, and the assertion acts as a tiny test.
Practical Tips
Keep functions short enough to read on one screen. If a function needs comments to separate its stages, those stages are often better as separate functions with clear names. In notebooks, move stable functions into a .py module and import them, so the same logic is shared across analyses instead of being copied between cells and drifting apart over time.
Finally, give functions verb-based names such as clean_prices or load_orders, so the call site reads like a description of the work being done.
Before writing a function, try writing the call you want to make. If the call reads clearly, the signature is probably right; if it needs many arguments, the function may be doing too much.
Common Mistakes
- Printing results instead of returning them.
- Changing the input DataFrame in place unexpectedly.
- Relying on global variables inside the function.
- Writing one function that does many unrelated jobs.
Quick Summary
- Use def, clear parameters and a return value.
- Keep each function focused on one task.
- Add type hints and a docstring.
- Test small functions with assertions.
Conclusion
Writing good functions is one of the most important skills in data science. In 2026, the standard is to define functions with type hints, comprehensive docstrings, and clear single responsibility. Well-designed functions make your data science code reusable, testable, and much easier to maintain as projects grow.
Next steps:
- Review your current data science scripts and refactor repeated logic into well-documented, typed functions