7

Studied myself into a corner again...

def superfunction(*args, **kwargs, k):
                                 ^
SyntaxError: invalid syntax

Whats the rule Im breaking here? It seems that youre not supposed to mix 'regular' variables with * variables, but I cant find anyone to confirm or deny this. I read somewhere (and I cant find in now of course) that some types of arguments have to come first, I believe keyword arguments, which may or may not be part of my issue.

jason
  • 4,721
  • 8
  • 37
  • 45
  • The details of exactly why this is wrong are a bit different between Python 2.x and 3.x; see the tutorial section [Keyword Arguments](http://docs.python.org/2/tutorial/controlflow.html#keyword-arguments) and the reference section [Function definitions](http://docs.python.org/2/reference/compound_stmts.html#function) for your appropriate version have the details. But briefly, nothing can come after the `**` parameter. – abarnert Aug 26 '13 at 21:31
  • I've also got a [blog post](http://stupidpythonideas.blogspot.com/2013/08/arguments-and-parameters.html) that explains the full details; I don't think it's at all novice-friendly… but I hope it's at least a little easier than reading the reference docs. (It is Python 3-specific, however.) – abarnert Aug 26 '13 at 21:46

2 Answers2

18

Try this:

def superfunction(k, *args, **kwargs):

The **kwargs variable keyword parameter must be the last part in the function declaration. Second-to-last, the *args variable position parameter. (In Python 3.x only, you can also have keyword-only parameters between *args and **kwargs.) And in the first places, the positional parameters - that's the correct way to declare function parameters. Take a look at this post for additional details.

For the full reference, see the Function definitions section in Python 3.x or Python 2.x.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 2
    so its unnamed vars, named vars, *, ** – jason Aug 26 '13 at 21:29
  • The only order I can get it to work in is def superfunction(k, n = 2 , *args, **kwargs): Thank you for putting me on the right track. – jason Aug 26 '13 at 21:30
  • followup : def superfunction(k, n = 2 , *args, *args2, **kwargs): Having multiple * type arguments throws a syntax error too. I guess youre only allowed one? – jason Aug 26 '13 at 21:31
  • This isn't quite right for Python 3.x, because you can also have keyword-only arguments between the `*args` and `**kwargs`. But either way, you can't have anything after the `**kwargs`, and you can't have more than one `*args` or more than one `**kwargs`. – abarnert Aug 26 '13 at 21:32
  • That's right, only one is allowed. I edited my answer with an useful link – Óscar López Aug 26 '13 at 21:33
  • Thank you Oscar. Reading it now. To anyone struggling with *args, read *args as 'multiple arguments' and it makes sense (to me anyway). – jason Aug 26 '13 at 21:35
  • Your answer used "arguments" where it should have used "parameters". I've edited it; feel free to revert if you disagree. – abarnert Aug 26 '13 at 21:35
  • @jason: Exactly, the `*args` parameter takes all the excess positional arguments, and `**kwargs` takes all the excess keyword arguments, so it doesn't makes sense to have positional parameters after `*args`, or _any_ kind of parameters after `**kwargs`, or two of either. – abarnert Aug 26 '13 at 21:35
  • @abarnert no need to revert, I agree :) – Óscar López Aug 26 '13 at 21:36
  • Keyword only parameters between `*args` and `**kwargs` are allowed also in 2.6 and 2.7 – Nicola Musatti Aug 26 '13 at 21:51
  • @NicolaMusatti: Are you sure? The [2.7 reference](http://docs.python.org/2.7/reference/compound_stmts.html#function) doesn't allow it (compare it to the 3.x version), the release notes don't say anything about it, `def foo(a, *b, c=2, **d): pass` raises a `SyntaxError` in 2.7, and [PEP 3102](http://www.python.org/dev/peps/pep-3102/) has version 3.0 as the target. – abarnert Aug 26 '13 at 21:55
  • Sorry, I confused *defining* middle keyword-only arguments with *using* them. The latter is indeed possible in 2.6 and 2.7 (but not 2.5) – Nicola Musatti Aug 26 '13 at 22:14
4

Syntax should be like this:

def superfunction(k, *args, **kwargs):

First you give all the positional arguments, then non-keyword arguments, and then keyword arguments.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Besides getting arguments and parameters wrong… non-keyword arguments and positional arguments are the same thing, so this is confusing and wrong. – abarnert Aug 26 '13 at 21:43
  • The right order is: positional-or-keyword params, then optionally `*args` (or `*`, in Python 3.x only), then (in Python 3.x only) keyword-only params, then `**kwargs`. – abarnert Aug 26 '13 at 21:45
  • @abarnert Ah! Is it? I read it few months back, so I seem to forgot the technical term, and hence a mix-up. Thanks for pointing that out. – Rohit Jain Aug 26 '13 at 21:47