По состоянию на Python 3.6, the keyword argument order is preserved. До 3.6 это невозможно, так как OrderedDict
превращается в dict
.
Первое, что нужно понимать, что значение вы передаете в **example
не автоматически становится значением в **kwargs
. Рассмотрим случай, когда kwargs
будет иметь только часть example
:
def f(a, **kwargs):
pass
example = {'a': 1, 'b': 2}
f(**example)
Или этот случай, где он будет иметь больше значения, чем в примере:
example = {'b': 2}
f(a=1, c=3, **example)
или даже без перекрытия на всех:
example = {'a': 1}
f(b=2, **example)
Итак, что вы просите не имеет смысла.
Тем не менее, было бы хорошо, если бы каким-нибудь способом, чтобы определить, что вы хотите упорядоченный **kwargs
, независимо от того, где ключевых слов пришли из-явных ключевых слов аргументов в порядке их появления, а затем все предметы **example
в том порядке, в котором они отображаются в example
(что может быть произвольным, если example
были dict
, но также могут иметь смысл, если это был OrderedDict
).
Определить все детали, затрудняющие работу, и обеспечить приемлемую производительность, оказывается сложнее, чем кажется. См. PEP 468 и связанные темы для обсуждения этой идеи. На этот раз он зашел в тупик, но если кто-то его подхватит и защитит (и пишет ссылку для людей, с которыми можно играть, что зависит от OrderedDict
, доступного из C API, но, мы надеемся, будет там в 3.5+), Я подозреваю, что он в конечном итоге попадет на этот язык.
Кстати, обратите внимание, что если это были возможно, он почти наверняка будет использоваться в конструкторе для самого OrderedDict
. Но если вы попытаетесь это сделать, все, что вы делаете замерзает некоторый произвольный порядок в качестве постоянного порядка:
>>> d = OrderedDict(a=1, b=2, c=3)
OrderedDict([('a', 1), ('c', 3), ('b', 2)])
Между тем, какие варианты у вас есть?
Ну, очевидный вариант просто передать example
как обычный аргумент вместо распаковки:
def f(example):
pass
example = OrderedDict([('a', 1), ('b', 2)])
f(example)
Или, конечно, вы можете использовать *args
и передавать предметы, как кортежи, но это обычно уродливее ,
В потоках, связанных с PEP, могут возникнуть некоторые другие обходные пути, но на самом деле ни один из них не будет лучше этого. (За исключением ... IIRC, Ли Хаойи придумал решение, основанное на его MacroPy, чтобы передать аргументы ключевого слова, сохраняющие порядок, но я не помню подробностей. Решения MacroPy в целом удивительны, если вы готовы использовать MacroPy и писать код который не совсем читается как Python, но это не всегда подходит ...)
Спасибо за подробные ответы. То, что я закончил, это разрешить необязательный первый аргумент (упорядоченный dict), который будет использоваться в предпочтении ** kwargs, если он предоставлен. Отличная информация, хотя – theodox
** Смотрите также: ** https://duckduckgo.com/?q=pep468 – dreftymac