从Python 3.6开始,关键字参数顺序被保留。在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
,无论 哪里 的关键字从- 明确的关键字ARGS中出现的顺序来了,然后是所有的项目**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,Li Haoyi提出了一个基于MacroPy的解决方案来传递保留顺序的关键字参数,但是我不记得详细信息。如果您愿意使用MacroPy并编写代码,那么MacroPy解决方案通常很棒读起来不像Python,但这并不总是合适的……)