198

Как «аргументы ключевого слова» отличаются от обычных аргументов? Могут ли все аргументы передаваться как name=value вместо использования позиционного синтаксиса?Стандартные аргументы Python против аргументов ключевого слова

+5

Возможно, вы также захотите прочитать PEP 3102 - они убирают некоторые из этих материалов в Python 3. См .: http://www.python.org/dev/peps/pep-3102/ –

+0

И независимо от того, не есть значение по умолчанию, не имеет ничего общего с ним (кроме того, нужно ли вам передавать значение для него), правильно? – mk12

+0

Подробнее о [python positional/keyword arguments] (http://symfony-world.blogspot.com/2013/07/python-positional-arguments-and-keyword.html) – ducin

ответ

256

Существуют две связанные концепции, называемые «аргументы ключевых слов».

На вызывающей стороне, о которой упоминали другие комментаторы, у вас есть возможность указать некоторые аргументы функции по имени. Вы должны упомянуть их после всех аргументов без имен (позиционные аргументы), и должны быть значения по умолчанию для любых параметров, которые вообще не упоминались.

Другая концепция относится к стороне определения функции: вы можете определить функцию, которая принимает параметры по имени, - и вам даже не нужно указывать, что это за имена. Это чистые аргументы ключевого слова и не могут быть переданы позиционно. Синтаксис:

def my_function(arg1, arg2, **kwargs) 

Любые аргументы ключевого слова, которые вы передадите в эту функцию, будут помещены в словарь с именем kwargs. Вы можете просмотреть ключи этого словаря во время выполнения, как это:

def my_function(**kwargs): 
    print str(kwargs) 

my_function(a=12, b="abc") 

{'a': 12, 'b': 'abc'} 
+3

+1 и принят: вы единственный, кто говорил об обоих типах позиционных + аргументов ключевого слова, все остальные думали, что я говорю о первом или втором (но они все еще были хорошими сообщениями). Благодаря! – mk12

+17

Формулировка неясна: обычно вы говорите о аргументах на вызывающей стороне, а параметры на вызываемой стороне. – glglgl

20

Существует два способа присвоения значений аргумента функциональным параметрам, оба используются.

  1. По положению. Позиционные аргументы не имеют ключевых слов и назначаются первыми.

  2. Ключевое слово. Аргументы ключевого слова имеют ключевые слова и назначаются вторым, после позиционных аргументов.

Обратите внимание, что вы имеют возможность использовать позиционные аргументы.

Если вы не использовать позиционные аргументы, то - да - все вы писали оказывается ключевым словом аргумента.

Когда вы используете, вызовите функцию, в которой вы принимаете решение использовать позицию или ключевое слово или смесь. Вы можете выбрать все ключевые слова, если хотите. Некоторые из нас не делают этого выбора и используют позиционные аргументы.

+1

О, я думал о параметрах, когда на самом деле это аргументы (что * I * проходит). Благодаря! – mk12

+2

Если бы я мог принять два твоих, то следующий. – mk12

80

Использование аргументов ключевого слова - это то же самое, что и обычные аргументы, за исключением того, что порядок не имеет значения. Например две функции вызовы ниже одинаковы:

def foo(bar, baz): 
    pass 

foo(1, 2) 
foo(baz=2, bar=1) 
+0

Спасибо за это.Это невероятно полезно, что я могу ** оба ** указать ключевое слово arg как позиционный arg, ** и ** позиционный arg как ключевое слово arg. –

32

позиционные аргументы

У них нет ключевых слов перед ними. Порядок важен!

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) 
+3

IMHO, третий пример (аргументы по умолчанию) не ясен. Я думаю, вы говорите о том, что происходит, когда один или несколько параметров объявляют значения по умолчанию, а вызов использует позиционную нотацию, но поставляет МЕНЬШЕ, чем количество объявленных параметров. Тем не менее, ваш пример имеет 3 объявленных и 3 в вызове, поэтому значения по умолчанию не имеют никакого эффекта! Вы намеревались опустить 3-й арг. например 'func (" bar ", 5)'? А затем скажите, что 'hello' получает значение по умолчанию' 3'. – ToolmakerSteve

10

Я удивлен, что никто не упомянул о том, что вы можете смешивать позиционные и именованные аргументы, чтобы сделать трусливые вещи, как это с помощью *args и **kwargs (from this site):

def test_var_kwargs(farg, **kwargs): 
    print "formal arg:", farg 
    for key in kwargs: 
     print "another keyword arg: %s: %s" % (key, kwargs[key]) 

Это позволяет используйте произвольные аргументы ключевых слов, которые могут иметь ключи, которые вы не хотите определять заранее.

138

Существует одна из последних особенностей языка, где важное значение имеет различие. Рассмотрим следующую функцию:

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'} 

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

+0

Отличный ответ! Просто обратите внимание, что требуемые позиционные аргументы могут быть переданы перед '* positional' и' ** keywords', если мы изменим определение функции как 'def foo (arg1, * positional, ** keywords):'. Здесь 'arg1' является позиционным и обязательным. Обратите внимание, что позиционный в ответе означает необязательное и переменное число позиционных аргументов. – shaffooo

18

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

>>> 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 
>>> 
+9

+1 для полезной техники. Ваша точка будет более ясной, без ', ** kwargs'. Это продемонстрировало бы, что даже простой func def с фиксированным # параметрами может быть предоставлен словарь. То есть, в определении не требуется ничего особенного. Затем вы можете добавить второй пример: WITH ** kwargs в определении и показать, как доступны EXTRA в словаре. – ToolmakerSteve

+0

Я видел, как это происходило в исходном коде различных библиотек и было настолько запутано. Спасибо, что поняли! –

+2

Четвертый формальный параметр выше - ** kwargs необходим, если вы когда-либо вызываете func со словарем, который содержит ключи, отличные от 'a', 'b' и 'c'. – Eduardo

11

Использование Python 3 вы можете иметь как требуется и не требуется ключевое слово arguments:

Дополнительный: (значение по умолчанию, определенное для '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'` 

Это может помочь в случаях, когда у вас есть много аналогичных аргументов рядом друг с другом, особенно в том же типе, в этом случае я предпочитаю использовать именованные аргументы или я создаю собственный класс, если аргументы принадлежат друг другу.

+2

Вариант * обязательно * весьма полезен. Он настоятельно призывает дать аргументы по имени без предоставления дефолтов, что часто не имеет смысла. – TNT

+0

Значения по умолчанию выглядят красиво и могут помочь вам сэкономить время, когда вы начинаете, но по длительным значениям по умолчанию могут быть PITA. –

Смежные вопросы