Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)

like image 327
ibarrond Avatar asked Jan 09 '20 09:01

ibarrond


People also ask

What happens when we prefix a parameter with two asterisk (*)?

What does ** (double star) and * (star) do for parameters? They allow for functions to be defined to accept and for users to pass any number of arguments, positional ( * ) and keyword ( ** ).

What is a star parameter Python?

The asterisk (star) operator is used in Python with more than one meaning attached to it. For numeric data types, * is used as multiplication operator >>> a=10;b=20 >>> a*b 200 >>> a=1.5; b=2.5; >>> a*b 3.75 >>> a=2+3j; b=3+2j >>> a*b 13j.


2 Answers

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 ... ) 
like image 133
Abdul Niyas P M Avatar answered Sep 20 '22 01:09

Abdul Niyas P M


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) 
like image 31
U12-Forward Avatar answered Sep 21 '22 01:09

U12-Forward