Usage of *[parameter name] and **[parameter name] in Python Functions

Translation Notice
This article was machine-translated using DeepSeek-R1.

  • Original Version: Authored in Chinese by myself
  • Accuracy Advisory: Potential discrepancies may exist between translations
  • Precedence: The Chinese text shall prevail in case of ambiguity
  • Feedback: Technical suggestions regarding translation quality are welcomed

I. *[parameter name]

Calling

Valid Calls

Regular Call

*parameter name is usually written as *args, e.g.:

1
2
def func(*args):
    print(args)

Try calling func:

1
2
3
4
5
6
7
8
>>> func(1)
(1,)
>>> func()
()
>>> func(1, 2, 3)
(1, 2, 3)
>>> func(dict(), set(), str(), int())
({}, set(), '', 0)

Thus, we observe that such functions can accept any number of arguments (including 0). * packs the arguments into a tuple, such as (1,), (), (1, 2, 3), ({}, set(), '', 0).

Special Call

If there’s already a tuple object to pass as args:
First define a tuple object:

1
2
3
>>> tuple_object = (1, 2, 3)
>>> print(tuple_object)
(1, 2, 3)
Wrong Approach

Common mistake:

1
2
>>> func(tuple_object)
((1, 2, 3),)

((1, 2, 3),)? Shouldn’t it be (1, 2, 3)?
The system treats it as a single argument in args, resulting in a “tuple within tuple” scenario. OH NO!

Correct Approach

Add * before tuple_object:

1
2
>>> func(*tuple_object)
(1, 2, 3)

This is called “unpacking”.

Invalid Calls

Trying func(a=1, b=2):

1
>>> func(a=1, b=2)

Triggers TypeError:

1
2
3
4
Traceback (most recent call last):
  File "<*args test file>", line 1, in <module>
    func(a=1, b=2)
TypeError: func() got an unexpected keyword argument 'a'

What’s a keyword argument?

  • keyword argument refers to parameter passing in name=value format.
  • Simply put, keyword argument means passing parameters as name=value pairs.

Thus, only positional arguments (value-only format) should be used here.

Default Parameters

Parameters with *[parameter name] cannot have default values:
Failed attempt to set default parameter

As shown, setting default parameters causes SyntaxError. To simulate default values:

1
2
3
4
5
6
# Manually set default values for *args
DEFAULT_VALUE = (1, 2, 3) # Customizable default
def func(*args):
    if args == (): # If empty (no arguments passed):
        args = DEFAULT_VALUE
    print(args)

Now it has default behavior:

1
2
>>> func() # No arguments
(1, 2, 3)

Summary

  • *[parameter name] indicates using positional arguments, accepts any number of arguments, packs them into a tuple.
  • Special call: *[tuple object]
  • Cannot set default parameters directly; requires manual default handling.

II. **[parameter name]

Calling

Valid Calls

Regular Call

**parameter name is usually written as **kwargs, e.g.:

1
2
def func(**kwargs): # kwargs = keyword arguments
    print(kwargs)

Calling func requires name=value format (hence kwargs):

1
2
3
4
5
6
>>> func(a=1, b=2, c=3, d=4)
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> func(_tuple_obj=tuple(), _set_obj=set(), _dict_obj=dict())
{'_tuple_obj': (), '_set_obj': set(), '_dict_obj': {}}
>>> func()
{}

Such functions accept any number of keyword arguments (including 0), packing them into a dict, such as {'a': 1, 'b': 2, 'c': 3, 'd': 4}, {'_tuple_obj': (), '_set_obj': set(), '_dict_obj': {}}, {}.

Special Call

If there’s a dict object to pass as kwargs:
Define the object:

1
2
3
>>> dict_object = {'a': 666, 'b': 888}
>>> print(dict_object)
{'a': 666, 'b': 888}

Then:

1
2
3
4
5
6
7
>>> func(dict_object) # Fails due to positional argument:
Traceback (most recent call last):
  File "<**kwargs test program>", line 1, in <module>
    func(dict_object)
TypeError: func() takes 0 positional arguments but 1 was given
>>> func(**dict_object) # Correct approach
{'a': 666, 'b': 888}

Invalid Calls

Passing positional arguments:

1
>>> func(1, 2)

Triggers TypeError:

1
2
3
4
Traceback (most recent call last):
  File "<**kwargs test program>", line 1, in <module>
    func(1, 2)
TypeError: func() takes 0 positional arguments but 2 were given

Only keyword arguments are allowed here.

Default Parameters

Similar to *args, use manual default handling:

1
2
3
4
5
6
# Manually set default values for **kwargs
DEFAULT_VALUE = {'a': 1, 'b': 2} # Customizable default
def func(**kwargs):
    if kwargs == {}: # If empty (no arguments passed):
        kwargs = DEFAULT_VALUE
    print(kwargs)

Now it has default behavior:

1
2
>>> func() # No arguments
{'a': 1, 'b': 2}

Summary

  • **[parameter name] indicates using keyword arguments, accepts any number of name=value pairs, packs them into a dict.
  • Special call: **[dict object]
  • Cannot set default parameters directly; requires manual default handling.
Built with Hugo
Theme Stack designed by Jimmy