3

Is there a way to implement a function that has variable number of arguments (*args) and also non-optional keyword arguments? I want to implement something like this:

def foo(positional arguments, keyword arguments,*args):

     {
      ...
     }

However, now there seems to be no way to call this function correctly. Let arg1 and arg2 be the arguments of type (*arg) that we want to pass in a function call.

foo(posargs, kwarg=value, arg1, arg2) 

is not allowed (kwargs have to be at last), while:

foo(posargs,arg1,arg2,kwarg=value)

would lead to a wrong function call, as then arg1 is positionally assigned to kwarg, inspite of kwarg being supplied a keyword value in the function call.

Is there any alternate defining or calling syntax that avoids this situation, (apart from the trivial solution of calling with kwarg values fed as positional arguments in the function call)?

B.coz
  • 33
  • 5

2 Answers2

3

This is a Python 3 feature, introduced in PEP 3102. (Python, default keyword arguments after variable length positional arguments)

In Python 2, you will have to extract the keyword arguments from **kwargs:

def foo(positional arguments, *args, **kwargs):
    # for a required positional argument
    try:
        kwarg = kwargs.pop('kwarg')
    except KeyError as e:
        raise TypeError('Required positional argument not found', e)

    # or for an optional positional argument
    kwarg = kwargs.pop('kwarg', None)

    if kwargs:
        raise TypeError('Unexpected positional arguments', kwargs)
Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366
0

*args will collect the unmatched positional arguments into a tuple. The **kwargs works to collect unmatched keyword arguments and puts them not into a tuple but into a dictionary.

From O'Reilly's Learning Python page 535:

def f(a, *pargs, **kargs):
    print (a, pargs, kargs)

f(1,2,3,x=1, y=2)
1 (2, 3), {'y':2, 'x':1}

From page 531 of the same book: "In both the call and header, the **args form must appear last if present. If you mix arguments in any other order, you will get a syntax error because the combinations can be ambiguous."

mba12
  • 2,702
  • 6
  • 37
  • 56
  • 1
    Yes, but i want to define the function with my own kargs rather than expecting the function-caller to supply the correct unmatched keyword argument (**kwargs). – B.coz Jul 26 '16 at 18:09
  • Not exactly what you are looking for but is there a reason you are ruling out passing a dict as one of your arguments since python won't accommodate what you want? – mba12 Jul 26 '16 at 19:47