python

When writing parameters, we tend to ask:

Is the parameter required, or can we use a default value?

def f(required, optional=None):

But there’s another question to ask:

Is its purpose obvious, or should it be named by the caller?

Placing an asterisk * in the parameter list forces all of the parameters following it to be named.

def f(
    unnamed_or_named_and_required,
    unnamed_or_named_and_optional=None,
    *,
    named_and_required,
    named_and_optional=None
):

If we want to catch any other un-named parameters, use a variable name following the asterisk (typically *args). This has the same effect as a bare-asterisk *; every parameter following it must be named.

def f(
    unnamed_or_named_and_required,
    unnamed_or_named_and_optional=None,
    *rest_of_unnamed,
    named_and_required,
    named_and_optional=None
):

To catch the rest of the named parameters, use double-asterisk with a name (typically **kwargs). This must come last.

def f(
    unnamed_or_named_and_required,
    unnamed_or_named_and_optional=None,
    *rest_of_unnamed,
    named_and_required,
    named_and_optional=None
    **rest_of_named
):

Unlike the single-asterisk, this catch-all can not be bare (**). It must be given a name; it would have no purpose without one.

Footnotes

When calling a function or class, pass unnamed, then named, then unpack unnamed, then unpack named.

f(unnamed, named="foo", *unpack_unnamed, **unpack_named)

There are a couple of PEPs (1, 2) proposing to add the capability to force parameters to be un-named. This would take the parameter groups to:

def f(
    unnamed_and_required,
    unnamed_and_optional=None,
    /,
    unnamed_or_named_and_required,
    unnamed_or_named_and_optional=None,
    *rest_of_unnamed,
    named_and_required,
    named_and_optional=None
    **rest_of_named
):