2

I have following code:

#!/usr/bin/python

import sys
import os

from pprint import pprint as pp

def test_var_args(farg, default=1, *args, **kwargs):
    print "type of args is", type(args)
    print "type of args is", type(kwargs)

    print "formal arg:", farg
    print "default arg:", default

    for arg in args:
        print "another arg:", arg

    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

    print "last argument from args:", args[-1]


test_var_args(1, "two", 3, 4, myarg2="two", myarg3=3)

Above code outputs:

type of args is <type 'tuple'>
type of args is <type 'dict'>
formal arg: 1
default arg: two
another arg: 3
another arg: 4
another keyword arg: myarg2: two
another keyword arg: myarg3: 3
last argument from args: 4

As you can see as a default argument is passed "two". But I do not want to assign to the default variable anything unless I say it explicitly. In other words, I want that aforementioned command returns this:

type of args is <type 'tuple'>
type of args is <type 'dict'>
formal arg: 1
default arg: 1
another arg: two
another arg: 3
another arg: 4
another keyword arg: myarg2: two
another keyword arg: myarg3: 3
last argument from args: 4

Changing the default variable should be done explicitly, e.g. using something like this (following command gives compilation error, it was just my attempt) test_var_args(1, default="two", 3, 4, myarg2="two", myarg3=3):

type of args is <type 'tuple'>
type of args is <type 'dict'>
formal arg: 1
default arg: two
another arg: 3
another arg: 4
another keyword arg: myarg2: two
another keyword arg: myarg3: 3
last argument from args: 4

I have tried following but it also returns an compilation error: test_var_args(1,, 3, 4, myarg2="two", myarg3=3)

Is this possible?

Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122
  • 5
    What is wrong with treating `default` as an optional `kwarg`, and including in your method the line `default = kwargs.get('default', 1)`? – Sam Jul 03 '15 at 07:49
  • Probably nothing, can you please post working code snippet in answer. I've tried to modify my code according your suggestion and added this `default = kwargs.get('default', 1)` as my first line in subroutine but it return me compilation error and/or takes 3 as a default value when called following way `test_var_args(1, 3, 4, myarg2="two", myarg3=3, default="default")` – Wakan Tanka Jul 03 '15 at 08:00
  • @WakanTanka Have a look at my answer, it contains a sample :D – wonderb0lt Jul 03 '15 at 08:01
  • Thank you guys, this helped – Wakan Tanka Jul 03 '15 at 08:13

1 Answers1

0

Unfortunately, I don't think that's possible.

As Sam pointed out, you could achieve the same behaviour by taking the value out of the kwargs. If your logic depends on kwargs not containing the "default" argument, you can just remove it from the kwargs dictionary using the pop method (see here). The following code behaves like you want it:

import sys
import os

from pprint import pprint as pp

def test_var_args(farg, *args, **kwargs):
    print "type of args is", type(args)
    print "type of args is", type(kwargs)

    print "formal arg:", farg
    print 'default', kwargs.pop('default', 1)

    for arg in args:
        print "another arg:", arg

    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

    print "last argument from args:", args[-1]

# Sample call
test_var_args(1, 3, 4, default="two", myarg2="two", myarg3=3)

which works similar to how you wanted in your question

wonderb0lt
  • 2,035
  • 1
  • 23
  • 37