Безопасно ли в Python передавать аргументы ключевых слов, которые не являются идентификаторами Python для функции? Вот пример:
>>> '{x-y}'.format(**{'x-y': 3}) # The keyword argument is *not* a valid Python identifier
'3'
>>> '{x-y}'.format(x-y=3)
File "<ipython-input-12-722afdf7cfa3>", line 1
SyntaxError: keyword can't be an expression
Я спрашиваю об этом, потому что мне удобнее форматировать имена, содержащие тире (поскольку значения соответствуют аргументу командной строки с тире в их имени). Но надежно ли это поведение (т. е. может ли оно варьироваться в зависимости от версии Python)?
Я не уверен, что использование неидентификаторов в качестве аргументов ключевого слова официально поддерживается: на самом деле документация гласит:
Если синтаксис **expression появляется в вызове функции, выражение должно оцениваться как сопоставление, содержимое которого обрабатывается как дополнительные аргументы ключевого слова.
… где «аргументы ключевого слова» определяются как имеющие имя, которое является идентификатором:
ключевое_аргументы ::= ключевое_элемент ("," ключевое_элемент)*
ключевое_элемент ::= идентификатор "=" выражение
где идентификаторы ограничены в том, какие символы они могут использовать ( -
например запрещено):
идентификатор ::= (буква|"_") (буква | цифра | "_")*
Итак, документация указывает, что сопоставление, данное **
в вызове функции, должно содержать только допустимые идентификаторы в качестве ключей, но CPython 2.7 принимает более общие ключи (для format()
и функций с аргументом **
, которые не помещают значения в переменные). Это надежная функция?
-
на_
в именах, чтобы сделать их действительными идентификаторами. Соглашение о вызовах**{...}
с именами, не являющимися идентификаторами, работает только в том случае, если вызываемая функция имеет аргумент**kw
для их получения, поскольку она также не может определять явные аргументы ключевых слов, которые не являются допустимыми идентификаторами. - person Martijn Pieters   schedule 06.06.2013**
гарантированно сработает, то в моем случае это более удобно (ключи словаря являются непосредственно именами параметров командной строки). - person Eric O Lebigot   schedule 06.06.2013kwargs
и**
когда-либо будут изменены, чтобы принимать какой-то особый тип отображения, который ограничивает его ключи допустимыми идентификаторами Python. - person martineau   schedule 06.06.2013**expression
. Функциональное описание ниже не ограничивает ключи словаря явно, равно как и документация по определению функции. Было бы огромным кошмаром обратной совместимости, чтобы когда-либо явно ограничивать это, чтобы вы были в безопасности. - person Martijn Pieters   schedule 06.06.2013**
). Спасибо! Не стесняйтесь вкладывать свои мысли в ответ на этот вопрос. :) - person Eric O Lebigot   schedule 06.06.2013**kwargs
вы можете просто передать словарь с произвольными ключами. Таким образом, не будет никакой неопределенности по этому поводу. - person Ber   schedule 06.06.2013str.format()
не не принимает словарь с произвольными ключами (эквивалентныйstring.Formatter.vformat()
принимает, но это не имеет значения). - person Eric O Lebigot   schedule 06.06.2013