3 ms·
If the function definition is `def f(x, y, a=None, b=None)`, you can already just call `f(*dict(a=1, x=98, y=99, b=2))`. So instead of using `0` and `1` for the
by shrimpx 3y ago
If the function definition is `def f(x, y, a=None, b=None)`, you can already just call `f(*dict(a=1, x=98, y=99, b=2))`. So instead of using `0` and `1` for the positions, like the tweet author suggests, you can just use the parameter names.
However, I've always disliked that you could do this in Python -- passing positional args out of order as kwargs. And also that you could pass kwargs as positional args.
Python 3 and later 3.8 introduced optional * and `/` in signature syntax to prevent both of these behaviors, which I appreciate, but IMO this should have been the default behavior from the beginning. Now you can prevent both behaviors by defining the function with `def f(x, y, /, *, a=None, b=None)`.
- DangitBobby 3y agoWhat's the benefit of prohibiting passing positional arguments by name?
- shrimpx 3y agoWhen args are positional-only, you can rename them without breaking callers. The names of the kwargs can be considered "external" and the names of the positional args remain private to the function. This gives authors flexibility to rename args, or even convert all the positional args to variadic `*args`, without affecting users. It also gives authors control over argument order. Like you write `def pow(x, y)`, conventionally meaning "x to the power y", and you don't want users to call it like `pow(y=2, x=3)`.