Python пытается поместить аргументы ключевого слова после * args

Я немного запутался в использовании *args.

Я хочу написать функцию, которая принимает переменное количество аргументов, но при этом может использовать преимущество определения предопределенного значения для ключевого аргумента.

Но невозможно написать такую ​​функцию:

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

Просто можно написать так:

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

Но затем я вызываю foo2 и передаю первый аргумент, который переопределяет значение по умолчанию для bar!.

foo2("somevalue")
somevalue ()

Где способ сделать это лучше ??

Я знаю, что мог бы написать так:

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

но что-то вроде определения первого метода (которое приводит к синтаксической ошибке) с моей точки зрения более интуитивно понятно.


person user2221323    schedule 16.03.2014    source источник
comment
При обновлении до Python 3.x вы можете использовать первую форму (см. legacy.python.org/dev/peps/pep-3102).   -  person jonrsharpe    schedule 16.03.2014


Ответы (2)


Вы должны использовать kwargs и выполнять назначение в вызове, а не определение:

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 

Который дает:

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

Вы можете использовать get, чтобы установить foo по умолчанию для bar следующим образом:

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)

Так что kwargs["bar"] всегда равно foo, если только оно не изменено явно:

(1, 2, 3) {'bar': 'foo'}
(1, 2, 3) {'bar': 'notboo'}
(1, 2, 3) {'bar': 'foo'}
person Chris Seymour    schedule 16.03.2014
comment
Я думал, что будет другой способ поместить значение по умолчанию в сигнатуру метода. Но я просто выбрал это решение, потому что не могу переключиться на Python 3. Спасибо, ребята! - person user2221323; 16.03.2014

Можете ли вы переключиться на python 3? В Python 3 вы можете использовать свой первый подход:

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

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

Ты получишь:

() newval
('hola2',) default_value
person Roberto    schedule 16.03.2014