Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a function's signature, what does the asterisk mean in Python when it's not followed by an identifier name? [duplicate]

Tags:

python

I know the meaning and usage of *args. But sometimes there is nothing like args after the *. For example, in the function pprint

def pprint(object, stream=None, indent=1, width=80, depth=None, *,
           compact=False):
    """Pretty-print a Python object to a stream [default is sys.stdout]."""
    printer = PrettyPrinter(
        stream=stream, indent=indent, width=width, depth=depth,
        compact=compact)
    printer.pprint(object)

there is an * in the signature. What does it mean?

like image 633
ziyuang Avatar asked Apr 14 '15 12:04

ziyuang


1 Answers

Arguments after the * are keyword-only. The * "soaks up" any additional positional arguments, so if you defined:

def foo(x, y, *, z):
    print(x, y, z)

then calling:

foo(1, 2, 3)

wouldn't work, as no z is supplied and only two positional arguments are expected:

>>> foo(1, 2, 3)
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    foo(1, 2, 3)
TypeError: foo() takes 2 positional arguments but 3 were given

z must now be supplied by keyword:

>>> foo(1, 2, z=3)
1 2 3

You can do this with a standard *args, but using * makes it clear that you don't want any additional positional arguments and causes an error to be raised if any end up in the *. As the PEP puts it:

The second syntactical change is to allow the argument name to be omitted for a varargs argument. The meaning of this is to allow for keyword-only arguments for functions that would not otherwise take a varargs argument

like image 50
jonrsharpe Avatar answered Oct 06 '22 00:10

jonrsharpe