11

In this question it is described that since Python3 you can use this notation:

def func(a, b, *args, kw1=None, **kwargs)

to define a function, instead of traditional Python2 way:

def func(a, b, kw1=None, *args, **kwargs)

Is there any agreed best practice which signature should be used or is it based on personal preference?

Community
  • 1
  • 1
PKuhn
  • 1,338
  • 1
  • 14
  • 30
  • [PEP-448](https://www.python.org/dev/peps/pep-0448/) implemented in pyton 3.5.2 brings more changes – Jerzyk Jul 03 '16 at 12:45

1 Answers1

11

There cannot be any "best" practice here, since those two definitions mean different (in a way, the opposite) things:

def func(a, b, kw1=None, *args, **kwargs):
    ...

means that the function will have an optional named argument kw1, which can be passed either as a keyword (func(1, 2, kw1=3)) or as an positional argument (func(1, 2, 3)). (In fact, unless specified explicitly with relatively new /-syntax, any named argument can be passed as a keyword.)

However, if a named arguments follows *args (or just *), it may be passed only as a keyword. For example:

def func(a, b, *, kw1=None, **kwargs):
    ...

cannot be called as func(1, 2, 3), and having

def func(a, b, *args, kw1=None, **kwargs):
    print(a, b, kw1)

func(1, 2, 3) will print 1, 2, None, because the positional argument goes to the *args part. (Thanks @tobias_k for pointing that out).

bereal
  • 32,519
  • 6
  • 58
  • 104
  • 2
    "cannot be called as func(1, 2, 3)" well, it can, but the `3` will go to `args`, not to `kw1` – tobias_k Jul 03 '16 at 13:00
  • 1
    you mixed up "keyword" and "positional" after the first code block –  Jul 03 '16 at 13:04
  • 1
    What kind of syntax is `func(a, b, *,...)`? Never saw that. Can you provide a reference? – tobias_k Jul 03 '16 at 15:02
  • 1
    @tobias_k it's [PEP 3102](https://www.python.org/dev/peps/pep-3102/) (_'The second syntactical change is to allow the argument name to be omitted for a varargs argument.'_) – bereal Jul 03 '16 at 15:05