Default and Flexible Arguments in Python Functions
Using default and flexible arguments effectively is a key skill for writing clean, reusable, and user-friendly functions in data science. In 2026, modern Python practices emphasize clear defaults, keyword-only arguments, and controlled flexibility.
TL;DR — Best Practices
- Use sensible default values for optional parameters
- Place default arguments after non-default ones
- Use keyword-only arguments (after
*) for important configuration options - Avoid mutable default arguments (lists, dicts, etc.)
1. Good Default Arguments Example
from typing import List, Optional
import pandas as pd
def preprocess_data(
df: pd.DataFrame,
target_column: str,
drop_na: bool = True, # Good default
scale_features: bool = False, # Sensible default
test_size: float = 0.2, # Common default in ML
random_state: Optional[int] = 42 # Reproducibility default
) -> dict:
"""
Preprocess data for machine learning.
"""
if drop_na:
df = df.dropna(subset=[target_column])
# Further preprocessing logic...
return {
"processed_df": df,
"test_size": test_size,
"random_state": random_state
}
2. Using Keyword-Only Arguments (Recommended for Configuration)
def train_model(
X_train,
y_train,
*,
model_type: str = "random_forest", # Keyword-only
n_estimators: int = 100, # Keyword-only
max_depth: Optional[int] = None, # Keyword-only
random_state: int = 42 # Keyword-only
):
"""
Train a model with clear configuration parameters.
Using * forces users to use keyword arguments for configuration.
"""
if model_type == "random_forest":
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=n_estimators,
max_depth=max_depth,
random_state=random_state
)
# ... other model types
model.fit(X_train, y_train)
return model
3. Avoiding Mutable Default Arguments (Important Gotcha)
# ❌ Bad practice - mutable default argument
def bad_function(data=[]): # Never do this!
data.append("item")
return data
# ✅ Correct way
def good_function(data=None):
if data is None:
data = []
data.append("item")
return data
4. Best Practices in 2026
- Provide sensible, commonly used default values
- Place all default parameters after non-default parameters
- Use keyword-only arguments (after
*) for configuration options to improve clarity - Never use mutable objects (lists, dicts, sets) as default values
- Use
Optional[...]from typing when a parameter can beNone - Document default behavior clearly in the docstring
Defaults and Flexible Arguments
Default arguments let callers skip common options, while *args collects extra positional values into a tuple and **kwargs collects extra keyword values into a dictionary. Together they let a function stay simple for typical calls and flexible for special ones.
A common pattern is passing **kwargs through to a library function, such as forwarding plotting options to pandas. Document which keys are expected so callers know what is allowed.
Worked Example: Forwarding Options
A helper accepts any number of columns and forwards extra options to round.
import pandas as pd
def mean_of(df, *columns, decimals=1, **kwargs):
cols = list(columns) or df.select_dtypes("number").columns.tolist()
return df[cols].mean(**kwargs).round(decimals)
df = pd.DataFrame({"a": [1, 2, 3], "b": [4.0, None, 6.0], "c": ["x", "y", "z"]})
print(mean_of(df, "a"))
print(mean_of(df, "a", "b", decimals=2))
print(mean_of(df, skipna=False))
With no columns given, the helper uses every numeric column. skipna=False is passed straight through to mean, so column b returns NaN because of its missing value.
Practical Tips
A useful safety measure is to validate kwargs against an allowed set, for example by raising a TypeError for unknown keys. That gives callers the same protection against typos that normal named parameters provide, while keeping the flexibility of forwarding options to a library.
Keep the number of defaults modest as well. A function with a dozen optional parameters is hard to learn, and splitting it into two focused functions is often clearer.
Common Mistakes
- Using mutable defaults such as lists.
- Swallowing misspelled keywords silently in **kwargs.
- Putting *args after keyword-only parameters by mistake.
- Not documenting which kwargs are forwarded.
Quick Summary
- Defaults simplify common calls.
- *args gathers positional extras.
- **kwargs gathers keyword extras.
- Forward kwargs carefully and document them.
Conclusion
Default and flexible arguments, when used correctly, make your data science functions much more convenient and professional. In 2026, the standard is to combine sensible defaults, keyword-only parameters for configuration, and careful avoidance of mutable defaults. These practices result in functions that are easier to use, less error-prone, and more maintainable.
Next steps:
- Review your current data science functions and improve their parameter design using default values and keyword-only arguments where appropriate