A new "positional-only parameters" syntax has been introduced in 3.8.
From Positional-only parameters in the documentation:
There is new syntax (
/
) to indicate that some function parameters must be specified positionally (i.e., cannot be used as keyword arguments). This is the same notation as shown byhelp()
for functions implemented in C (produced by Larry Hastings’ Argument Clinic tool).
Why ever use this syntax? Why is it better for the code's user?
It seems to me that this makes it harder for users to specify what their arguments actually mean, if they so desire. Why make it harder on the user?
To briefly summarize the stated rationales in PEP 570, the PEP that added positional-only arguments:
dict
type, take arbitrary keyword arguments. If you were to try to define a class with such behavior in python, you would have to write def __init__(self, **kwds)
, ... except then you can't have a keyword argument named self
!. Positional-only arguments can avoid this flaw.int
constructor. int(x="3")
is no more readable than int("3")
. Positional-only arguments allow names that have no inherent meaning to be considered implementation details rather than part of the public API of the module.There are a few more details in the PEP, but those three points summarize the general reason for the existence of the feature.
One reason is that people rename their function arguments and then all of the function calls which used keywords no longer work properly.
For example, given a function as follows:
def pow(base: float, exponent: int) -> float:
pass
you could write function calls using positional or keyword arguments:
pow(4.5, 10)
pow(4.5, exponent=10)
pow(exponent=10, base=4.5)
If the arguments were subsequently renamed:
def pow(base: float, exp: int) -> float:
"""
CHANGE LOG OR VERSION HISTORY:
`exponent` renamed to `exp`
"""
pass
then calls referring to the old argument names would give a TypeError
:
pow(4.5, 10) # OK
pow(4.5, exponent=10) # TypeError
pow(exponent=10, base=4.5) # TypeError
One potential rememdy is requiring consumers to use only positional arguments:
def pow(base: float, exponent: int, /) -> float:
pass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With