What do * (single star) and / (slash) do as independent parameters?

PythonPython 3.xFunctionParameter PassingFunction Parameter

Python Problem Overview


In the following function definition, what do the * and / account for?

def func(self, param1, param2, /, param3, *, param4, param5):
     print(param1, param2, param3, param4, param5)

NOTE: Not to mistake with the single|double asterisks in *args | **kwargs (solved here)

Python Solutions


Solution 1 - Python

There is a new function parameter syntax / to indicate that some function parameters must be specified positionally and cannot be used as keyword arguments.[This is new in Python 3.8]

Documentation specifies some of the use cases/benefits of positional-only parameters

> 1. It allows pure Python functions to fully emulate behaviors of > existing C coded functions. For example, the built-in pow() > function does not accept keyword arguments: >
> def pow(x, y, z=None, /): > "Emulate the built in pow() function" > r = x ** y > return r if z is None else r%z > 2. Another use case is to preclude keyword arguments when the parameter > name is not helpful. For example, the builtin len() function has > the signature len(obj, /). This precludes awkward calls such as: >
> len(obj='hello') # The "obj" keyword argument impairs readability > 3. A further benefit of marking a parameter as positional-only is that > it allows the parameter name to be changed in the future without > risk of breaking client code. For example, in the statistics module, > the parameter name dist may be changed in the future. This was made > possible with the following function specification: >
> def quantiles(dist, /, *, n=4, method='exclusive') > ...

Where as * is used to force the caller to use named arguments. This is one of the use case of named arguments.

So, given the method,

def func(self, param1, param2, /, param3, *, param4, param5):
     print(param1, param2, param3, param4, param5)

It must called with

obj.func(10, 20, 30, param4=50, param5=60)

or

obj.func(10, 20, param3=30, param4=50, param5=60)

ie,

  1. param1, param2 must be specified positionally.
  2. param3 can be called either with positional or keyword.
  3. param4 and param5 must be called with keyword argument.

DEMO:

>>> class MyClass(object):
...     def func(self, param1, param2, /, param3, *, param4, param5):
...         return param1, param2, param3, param4, param5
...
>>> obj = MyClass()
>>>
>>> assert obj.func(10, 20, 30, param4=40, param5=50), obj.func(
...     10, 20, param3=30, param4=40, param5=50
... )

Solution 2 - Python

As mentioned in the docs, the slash is for positional-only arguments, as the docs says:

> There is a new function parameter syntax / to indicate that some function parameters must be specified positionally and cannot be used as keyword arguments. This is the same notation shown by help() for C functions annotated with Larry Hastings’ Argument Clinic tool.

And for the asterisk, it's mentioned here in the docs:

> For a parameter with a default value, the corresponding argument may be omitted from a call, in which case the parameter’s default value is substituted. If a parameter has a default value, all following parameters up until the “*” must also have a default value — this is a syntactic restriction that is not expressed by the grammar.


def func(self, param1, param2, /, param3, *, param4, param5):
     print(param1, param2, param3, param4, param5)

So the ways to call this would be:

obj.func(10, 20, 30, param4=50, param5=60)

And:

obj.func(10, 20, param3=30, param4=50, param5=60)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionibarrondView Question on Stackoverflow
Solution 1 - PythonAbdul Niyas P MView Answer on Stackoverflow
Solution 2 - PythonU12-ForwardView Answer on Stackoverflow