Function Arguments and Calling
Once you start writing more functions, parameter design directly affects readability. Many functions that "work but aren't pleasant to use" have their problem not in the logic but in unclear parameter interfaces.
Positional Arguments
The most basic and common approach:
def greet(name, age):
print(f"{name} is {age} years old.")
greet("alice", 20)
Values are passed in order when calling.
Keyword Arguments
def greet(name, age):
print(f"{name} is {age} years old.")
greet(age=20, name="alice")
This approach is better when there are many parameters, or when parameters of the same type could easily be passed in the wrong order.
Default Arguments
def connect(host, port=3306):
print(host, port)
connect("localhost")
connect("localhost", 5432)
Default arguments reduce the cost of calling, but don't force "always-changing parameters" into default arguments.
*args: Accept any number of positional arguments
def total(*numbers):
return sum(numbers)
print(total(1, 2, 3, 4))
This is useful when the number of arguments is not fixed.
**kwargs: Accept any number of keyword arguments
def print_config(**kwargs):
for key, value in kwargs.items():
print(key, value)
print_config(host="localhost", port=3306, debug=True)
Parameter order should follow rules
When a function has a rich mix of parameter types, the order typically follows:
- Regular positional arguments
- Default arguments
*args- Keyword-only arguments
**kwargs
For example:
def func(a, b=0, *args, sep=",", **kwargs):
...
A very common pitfall: mutable default arguments
Not recommended:
def append_item(item, container=[]):
container.append(item)
return container
A safer approach:
def append_item(item, container=None):
if container is None:
container = []
container.append(item)
return container
The reason is that default arguments are created only once at function definition time, not recreated on every call.
Parameter design habits I recommend
- When parameters are few and clear, use positional arguments
- When the order is easy to get wrong, use keyword arguments
- Only use
*args/**kwargswhen you genuinely need variable arguments - Try to use immutable values for default arguments