Вопрос

I'm a bit confused about using *args.

I want to write a function that takes a variable number of arguments but can still use the advantage of defining a predefined value for a keyword argument.

But it's not possible to write a function like this:

def foo(*args, bar = "foo"):
    print bar, args

It's just possible to write it like this:

def foo2(bar = "foo", *args):
    print bar, args

But then I call foo2 and pass the first argument it overrides the default value for bar!.

foo2("somevalue")
somevalue ()

Is where a way of doing this better ??

I know I could write it like this:

def foo(*args, **kwargs):
    kwargs["bar"] = "foo"

but something like the first method definition (which yields a syntax error) is more intuitive from my point of view.

Это было полезно?

Решение

You would use kwargs and do the assignment in the call not the definition:

def foo2(*args, **kwargs):     # kwargs takes our key/values arguments
    print args, kwargs

foo2(1, 2, 3, bar="foo")       # bar is assigned to in call when using kwargs 

Which gives:

(1, 2, 3) {'bar': 'foo'} 

You could use get to set foo as a default for bar like so:

def foo2(*args, **kwargs):
    kwargs["bar"] = kwargs.get("bar", "foo") # if bar is not set use foo as val
    print args, kwargs

foo2(1, 2, 3, bar="foo")
foo2(1, 2, 3, bar="notfoo")
foo2(1, 2, 3)

So that kwargs["bar"] is always foo unless explicitly changed:

(1, 2, 3) {'bar': 'foo'}
(1, 2, 3) {'bar': 'notboo'}
(1, 2, 3) {'bar': 'foo'}

Другие советы

Can you switch to python 3 ?, In Python 3 you can use your first approach:

def foo(*args, bar = 'default_value'):
    print (args, bar)

foo(bar = 'newval')
foo('hola2')

You'll get:

() newval
('hola2',) default_value
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top