Чем «аргументы ключевых слов» отличаются от обычных аргументов? Не могут ли все аргументы передаваться name=value
вместо использования позиционного синтаксиса?
Чем «аргументы ключевых слов» отличаются от обычных аргументов? Не могут ли все аргументы передаваться name=value
вместо использования позиционного синтаксиса?
Ответы:
Есть две взаимосвязанные концепции, обе называются « аргументами ключевых слов ».
На вызывающей стороне, о которой упоминали другие комментаторы, у вас есть возможность указать аргументы некоторых функций по имени. Вы должны упомянуть их после всех аргументов без имен ( позиционные аргументы ), и должны быть значения по умолчанию для любых параметров, которые не были упомянуты вообще.
Другая концепция находится на стороне определения функции: вы можете определить функцию, которая принимает параметры по имени - и вам даже не нужно указывать, что это за имена. Это чисто ключевые аргументы , и они не могут быть переданы позиционно. Синтаксис
def my_function(arg1, arg2, **kwargs)
Любые ключевые слова , передаваемые в эту функцию, будут помещены в словарь с именем kwargs
. Вы можете проверить ключи этого словаря во время выполнения, например так:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
kwargs
или я могу переименовать его в sth. как options
( def my_fuction(arg1, arg2, **options)
)?
kwargs
это соглашение, когда нет более подходящего имени
Есть одна последняя языковая особенность, где различие важно. Рассмотрим следующую функцию:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
*positional
Аргумент будет хранить все позиционные аргументы , передаваемые foo()
, без ограничения, сколько вы можете предоставить.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
**keywords
Аргумент будет хранить любые именованные аргументы:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
И, конечно же, вы можете использовать оба одновременно:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
Эти функции используются редко, но иногда они очень полезны, и важно знать, какие аргументы являются позиционными или ключевыми словами.
*positional
и **keywords
если мы изменим определение функции, как def foo(arg1, *positional, **keywords):
. Здесь arg1
позиционный и обязательный. Обратите внимание, что позиционный в ответе означает необязательное и переменное количество позиционных аргументов.
foo(bar=True)
вы можете получить значения, используя те bar = keywords.pop('bar')
же, что и bar = keywords.pop('bar', None)
. Для значения по умолчанию используйтеbar = keywords.pop('bar', False)
Использование аргументов с ключевыми словами - это то же самое, что и обычные аргументы, за исключением того, что порядок не имеет значения. Например, два вызова функций ниже одинаковы:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
У них нет ключевых слов перед ними. Порядок важен!
func(1,2,3, "foo")
У них есть ключевые слова в передней части. Они могут быть в любом порядке!
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
Вы также должны знать, что если вы используете аргументы по умолчанию и пренебрегаете вставкой ключевых слов, тогда порядок будет иметь значение!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
func("bar", 5)
? А потом скажите, что hello
получает значение по умолчанию 3
.
Есть два способа присвоить значения аргумента параметрам функции, оба используются.
По позиции. Позиционные аргументы не имеют ключевых слов и назначаются первыми.
По ключевому слову. Аргументы ключевых слов имеют ключевые слова и назначаются вторыми после позиционных аргументов.
Обратите внимание, что вы есть возможность использовать позиционные аргументы.
Если вы не используете позиционные аргументы, тогда - да - все, что вы написали, оказывается ключевым аргументом.
Когда вы вызываете функцию, вы принимаете решение использовать позицию, ключевое слово или их комбинацию. Вы можете сделать все ключевые слова, если хотите. Некоторые из нас не делают этого выбора и используют позиционные аргументы.
Я удивлен, что никто, кажется, не указал, что можно передать словарь параметров аргументов с ключами, которые удовлетворяют формальным параметрам, вот так.
>>> def func(a='a', b='b', c='c', **kwargs):
... print 'a:%s, b:%s, c:%s' % (a, b, c)
...
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>>
, **kwargs
. Это продемонстрирует, что даже простой func def с фиксированным числом параметров может быть снабжен словарем. То есть в определении не требуется ничего особенного. Тогда вы можете добавить второй пример, с определением WITH ** kwargs, и показать, как через него доступны ДОПОЛНИТЕЛЬНЫЕ элементы в словаре.
print 'a:%s, b:%s, c:%s' % (a, b, c)
дает синтаксическую ошибку, однако print('a:%s, b:%s, c:%s' % (a, b, c))
работает. Что-то с версией Python? В любом случае, спасибо за это понимание, до сих пор я использовал более неуклюжийprint('a:{}, b:{}, c:{}'.format(a, b, c))
Используя Python 3, вы можете иметь как обязательные, так и необязательные ключевые аргументы :
Необязательно : (значение по умолчанию определено для параметра 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
Обязательно (значение по умолчанию для параметра 'b' не определено):
def func2(a, *, b):
...
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`
Это может помочь в тех случаях, когда у вас много похожих аргументов рядом друг с другом, особенно если они одного типа, в этом случае я предпочитаю использовать именованные аргументы или создаю собственный класс, если аргументы принадлежат друг другу.
Я удивлен, что никто не упомянул тот факт, что вы можете смешивать позиционные и ключевые аргументы, чтобы делать такие хитрые вещи, используя *args
и **kwargs
( с этого сайта ):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
Это позволяет вам использовать произвольные аргументы ключевых слов, которые могут иметь ключи, которые вы не хотите задавать заранее.
Я искал пример, который имел kwargs по умолчанию, используя аннотацию типа:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
пример:
>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
Просто добавьте / добавьте способ определения значения аргументов по умолчанию, которое не присваивается в ключевых словах при вызове функции:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
позвоните по этому:
print(func())
print(func(my_word='love'))
ты получишь:
default_msg
love
Узнайте больше о *args
и **kwargs
в Python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3