Как зовут ** в Python?

59

При программировании на Python я иногда делаю **конверсию. Я понимаю, что он делает, но какими структурами данных я манипулирую? А dictкакой другой? array? Есть ли название для **оператора?

Никлас Розенкранц
источник
3
экспоненциальный оператор?
Ладья
12
Есть два значения для **. Мощность и «словарь аргумента ключевого слова». О чем ты говоришь? В документации есть следующие слова: «Если присутствует форма« ** идентификатор », она инициализируется новым словарем, получающим любые лишние аргументы ключевого слова, по умолчанию новым пустым словарем». Какие из них кажутся актуальными для вашего вопроса?
С.Лотт
"словарь аргумента ключевого слова" был тем, о котором я спрашиваю. Спасибо за комментарии.
Никлас Розенкранц

Ответы:

86

Это не оператор как таковые, так что это не на самом деле есть имя, но оно определяется как «синтаксическое правило» . Так и должно называться:

  • "синтаксис распаковки аргумента ключевого слова"

Если у вас есть список аргументов, *argsэто называется «распаковка аргумента» , таким же образом **kwargsназывается «распаковка аргумента ключевого слова» .

Если вы используете его с левой стороны =, как, например a, *middle, end = my_tuple, вы бы сказали «распаковка кортежей» .

Всего существует три типа аргументов (с одним параметром):

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

*argsАргумент называется «переменным позиционным параметром» и **kwargsявляется «переменным ключевым словом параметра». Аргументы только для ключевого слова не могут быть заданы позиционно, поскольку переменный позиционный параметр будет принимать все передаваемые вами аргументы.

Большая часть этого может быть найдена в PEP 0362 и 3102 , а также в разделе « Поток управления» документов. Однако следует отметить, что объект сигнатуры функции PEP является всего лишь черновиком, и терминология может быть просто идеей одного человека. Но они все равно хорошие условия. :)

Таким образом, *и **аргументы , просто распакуйте их соответствующие структуры данных:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

f(*args)  f(1, 2, 3)

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables - это объекты, которые реализуют __iter__()метод, а отображения - это объекты, которые реализуют keys()и __getitem__(). Любой объект, который поддерживает этот протокол, будет понят конструкторам tuple()и dict(), следовательно, их можно использовать для распаковки аргументов.

Стефано Палаццо
источник
3
В случае, если кто-то еще смущен, def f(x, *xs, y=0): passнедопустим синтаксис Python 2. {5,6,7}, и он не def f(x, y=0, *xs):выполняет то, что вы ожидаете. AFAIK, единственный способ достичь (очевидно) предполагаемого эффекта def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 обрабатывает оригинальный синтаксис, как и ожидалось.
февраля
1
Пока мы на этом: begin, *middle, end = (0, 1, 2, 3, 4, 5)синтаксис не работает и в Python 2.x.
Стефано Палаццо
Этот ответ неверен в Python 3.5 и более поздних версиях. PEP-448 определяет оператор ** в качестве оператора распаковки словаря. См. Python.org/dev/peps/pep-0448
devnul3
13

Я не думаю, что у него есть имя. В Python Docs в разделе «Распаковка списков аргументов» это просто упоминается как « **-оператор».

Я не уверен, что вы подразумеваете под "другой" структурой данных. Когда вы f(**kwargs)распаковываете словарь kwargsкак последовательность пар ключ-значение. Я не вижу, чтобы была задействована другая структура.

Я скопирую пример в вышеупомянутой документации для ясности.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Смотрите также: Что означают * args и ** kwargs?

Крис Харпер
источник
Существует несколько возможных способов интерпретации читателем f(**kwargs)...
Охотник на оленей
3

Если вы не знаете, как позвонить конкретному оператору или если он не назван, вы всегда можете обратиться к Waka Waka Bang Splat в качестве справки, чтобы помочь вам понять, как его назвать. В этом случае **я бы назвал это double-splat, хотя есть несколько альтернативных имен для символов .

aculich
источник