3

I have a python function (python 2.5) with a definition like:

def Foo(a, b='Silly', c='Walks', d='Spam', e='Eggs', f='Ni', *addl):

Where addl can be any number of strings (filenames) to do something with.

I'm fine with all of the defaults, but I have filenames to put in addl.

I am inclined to do something like:

Foo('me@domain.com', addl=('File1.txt', 'File2.txt'))

But that gets the following error:

TypeError: Foo() got an unexpected keyword argument 'addl'

Is there a syntax where I can succinctly call Foo with just the first required parameter and my (variable number of) additional strings? Or am I stuck redundantly specifying all of the defaults before I can break into the addl argument range?

For the sake of argument, the function definition is not able to be modified or refactored.

  • Just unpack tuple, it should work: Foo('me@domain.com', *('File1.txt', 'File2.txt')) – AndreyT Apr 04 '16 at 14:40
  • 2
    @AndreyT: That doesn't work. It assigns `'File1.txt'` to `a`, and `'File2.txt'` to `b`. – zondo Apr 04 '16 at 14:42
  • 1
    Yep, you right. So, in case of 2.5 possible solution is usage kwargs instead of b,c,d,e,f parameters. – AndreyT Apr 04 '16 at 14:50
  • @AndreyT It is not specific to `Python 2.5`, right? Can we say that it hold true for `Python>2.5`? I tried this on `Python 2.7` and assigns `File2.txt` to `b` as well. – malhar Apr 04 '16 at 14:53
  • @AndreyT: The problem with that would be the unmitigated affect on all the other code using `Foo` – MellowNello Apr 04 '16 at 14:55
  • 1
    @malhar: It's bit specific to 2.x. In 3.x we can use folow definition: def f(a, *args, b=1, c=2, etc=3) – AndreyT Apr 04 '16 at 15:00

3 Answers3

2

Ok, if function can't be modified, then why not create wrapper?

def foo_with_defaults(a, *addl):
    Foo(a, *(Foo.func_defaults + addl))

foo_with_defaults('me@domain.com', *('File1.txt', 'File2.txt'))
AndreyT
  • 1,299
  • 12
  • 24
0

To my knowledge it is not possible.

First you need to pass required (a) and default (b, c, d, e, f) arguments, and then every additional argument is passed as *addl:

Foo('me@domain.com', 'Silly', 'Walks', 'Spam', 'Eggs', 'Ni', 'File1.txt', 'File2.txt')
apr
  • 360
  • 1
  • 5
  • 2
    So your answer to "is there a syntax where I can succinctly call Foo with just the first required parameter and my (variable number of) additional strings?" is "no"? Are you certain this is the one and only approach? – Kevin Apr 04 '16 at 14:52
  • Sorry for not answering the question precisely. To my knowledge it is not possible. I will edit my answer. – apr Apr 04 '16 at 14:58
0

You are trying to use addl as a keyword argument, but you defined it as a positional argument. You should add one more * if you want to call the function like Foo(addl=('File1.txt', 'File2.txt')):

def Foo(a, b='Silly', c='Walks', d='Spam', e='Eggs', f='Ni', **addl):
Pablo Díaz Ogni
  • 983
  • 6
  • 12