-2

With the introduction of the slash character to specify position-only arguments, is it recommended to put a slash in every method after the self parameter?

For example:

class A:
    def something(self, /, some_arg):

Many built-in objects seem to do so (see range, str.encode, etc.).

Is there some sort of advantage (maybe security related?) in explicitly prohibiting the self parameter from being set as a keyword argument? Or is this just for clarity in interface specifications?

1
  • In CPython, these builtins are implemented in C, and the Python C API is kind of awkward for passing arguments to functions, especially if you need to accept keyword arguments. It seems likely that this is more about YAGNI than for any other reason.
    – Jasmijn
    Jul 8 at 11:54

1 Answer 1

3

No, it is not generally sensible to use the PEP-570 positional-only arguments that are available since Python 3.8.

When you define a function def foo(a, b), then you can use the arguments as either positional or named arguments. All of these are equivalent:

foo(1, 2)
foo(1, b=2)
foo(a=1, b=2)
foo(b=2, a=1)

But sometimes, you want keyword-only or positional-only arguments.

  • By using a *, you can force keyword-only arguments.
    When we have def foo(*, a, b) then only foo(a=1, b=2) or foo(b=2, a=1) invocations are allowed.

  • By using a /, you can force positional-only arguments.
    When we have def foo(a, b, /) then only foo(1, 2) invocation is allowed.

So what def something(self, /, some_arg) tells us is that self can never be passed as a keyword argument. Does this make sense? Kind of yes, but this is not really important.

You see / in a lot of built-in functions because these are often implemented in C code, and they don't want to support keyword arguments for efficiency and simplicity reasons.

For maintainability, it is usually a very good idea to allow keyword arguments, or even to force keyword-only arguments. In contrast, positional-only arguments make most sense in these two cases:

  • You don't want to expose your parameter names as part of the public API. For example, you don't want that people can call some_function(123) as some_function(internal_name=123) because then renaming the parameter would be an API-breaking change. This doesn't really matter for methods since the self parameter is passed implicitly.

  • You have profiled your application and the data indicates that calls to this function are performance-critical. Calls with positional-only arguments are faster on recent Python versions. But don't start using positional-only arguments everywhere as a premature optimization!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.