How many arguments should a function have in Python? | Andros Fenollosa
One of the clearest signs that a function is doing too much is that it has too many arguments. When there are many arguments, the code becomes hard to read, test, and document. What is the limit?
A simple rule that works well in practice:
Ideal: 0 to 2 arguments.
Acceptable: 3 or 4 (if well justified or using default values).
Bad design: 5 to infinity.
But there are functions that need more arguments — for example, when creating a user, you need first name, last name, email, phone, address... There must be a solution that does not break the 4-argument rule.
Here are some tools to consider. You decide which one fits your case best.
Dataclasses
If you have several related arguments, group them into a dataclass. The function receives a single object with everything it needs.
from dataclasses import dataclass
@dataclass<br>class Address:<br>"""Full postal address of a user.
Attributes:<br>street: Street name and number.<br>city: City of residence.<br>zip_code: Postal code of the area.<br>"""
street: str<br>city: str<br>zip_code: str
def create_user(<br>first_name: str, last_name: str, email: str, phone: str, address: Address<br>) -> None:<br>"""Create a new user in the system.
Args:<br>first_name: User's first name.<br>last_name: Last name.<br>email: Email address.<br>phone: Contact phone number.<br>address: Full postal address.<br>"""<br># Your logic here<br>Keyword-only arguments
The * in the signature forces everything that comes after it to be passed by name. Its main advantage is that it improves readability, since the code that calls the function is more explicit.
def configure_chart(<br>title: str,<br>*,<br>width: int = 800,<br>height: int = 600,<br>line_color: str = "blue",<br>thickness: int = 2,<br>) -> None:<br>"""Configure and render a chart.
Args:<br>title: Chart title.<br>width: Width in pixels, default 800.<br>height: Height in pixels, default 600.<br>line_color: Main line color, default "blue".<br>thickness: Line thickness in points, default 2.<br>"""<br>pass
configure_chart("My Chart", width=1024, line_color="red")<br>Validation with msgspec
Work with a data validation library, for example msgspec. If you have used pydantic, you will feel right at home. Think of msgspec as a modern validator and parser, lightweight (written in C) and very efficient.
import msgspec
class User(msgspec.Struct, strict=True):<br>"""User model with strict type validation.
Attributes:<br>name: Full name of the user.<br>age: Age in years.<br>"""
name: str<br>age: int
input_data = {"name": "Ana", "age": 28}
validated_user = msgspec.convert(input_data, type=User)<br>With strict=True, if a type does not match exactly, it raises an error. No surprises.
Final notes
I have not included *args and **kwargs because they only hide the arguments. They are useful in specific contexts (decorators, wrappers, very generic APIs), but they are not an excuse to avoid thinking about design.
Hopefully, before adding a fifth argument, you ask yourself whether it really belongs there or whether it is a sign that the function is taking on too many responsibilities.
Dataclasses
Keyword-only arguments
Validation with msgspec
Final notes
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Will you buy me a coffee?
Support me on Ko-fi
Comments
page#run"<br>data-liveview-function="show_comment_email"<br>data-id="43e638f4"<br>data-type="article"<br>>Leave a comment
There are no comments yet.
You may also like
page#run"<br>data-liveview-function="navigate_article"<br>data-uuid="80134668">
python
django
django channels
websockets
django liveview
Django LiveView vs Phoenix LiveView: a real benchmark
page#run"<br>data-liveview-function="navigate_article"<br>data-uuid="3225552c">
python
Python Comments and Docstrings Best Practices
page#run"<br>data-liveview-function="navigate_article"<br>data-uuid="b5ba872a">
videojuegos
python
terminal
experiencia
streamlit
ai
Making UIs like text adventure games
Visitors in real time
You are alone: 🐱