the*_*dox 29 python parameter-passing kwargs
是否可以将OrderedDict实例传递给使用**kwargs语法并保留排序的函数?
我想做的是:
def I_crave_order(**kwargs):
for k, v in kwargs.items():
print k, v
example = OrderedDict([('first', 1), ('second', 2), ('third', -1)])
I_crave_order(**example)
>> first 1
>> second 2
>> third -1
Run Code Online (Sandbox Code Playgroud)
但实际结果是:
>> second 2
>> third -1
>> first 1
Run Code Online (Sandbox Code Playgroud)
即,典型的随机字典排序.
我有其他用途明确设置顺序是好的,所以我想保留**kwargs而不是仅仅将OrderedDict作为常规参数传递
aba*_*ert 29
从Python 3.6开始,保留关键字参数顺序.在3.6之前,由于OrderedDict变成了一个,所以不可能dict.
首先要意识到的是,传入的值**example不会自动成为值**kwargs.考虑这种情况,其中kwargs只有部分example:
def f(a, **kwargs):
pass
example = {'a': 1, 'b': 2}
f(**example)
Run Code Online (Sandbox Code Playgroud)
或者这种情况下,它将具有比示例中更多的值:
example = {'b': 2}
f(a=1, c=3, **example)
Run Code Online (Sandbox Code Playgroud)
甚至根本没有重叠:
example = {'a': 1}
f(b=2, **example)
Run Code Online (Sandbox Code Playgroud)
所以,你所要求的并没有多大意义.
不过,如果有一些方法来指定您希望它可能是不错的有序**kwargs,无论哪里的关键字从-明确的关键字ARGS中出现的顺序来了,然后是所有项目的**example顺序它们出现在example(这可能是任意的,如果example是a dict,但如果是a )也可能是有意义的OrderedDict.
定义所有繁琐的细节,并保持性能可接受,结果证明比听起来更难.有关该想法的一些讨论,请参阅PEP 468和链接的线程.这次似乎已经停滞不前了,但是如果有人拿起它并支持它(并为人们编写参考实现 - 这取决于OrderedDict可从C API访问,但希望在3.5+中可以使用) ,我怀疑它最终会进入语言.
顺便说一句,请注意,如果这是可能的,它几乎肯定会在构造函数中用于OrderedDict它自己.但是,如果你尝试这样做,你所做的只是冻结一些任意顺序作为永久订单:
>>> d = OrderedDict(a=1, b=2, c=3)
OrderedDict([('a', 1), ('c', 3), ('b', 2)])
Run Code Online (Sandbox Code Playgroud)
同时,你有什么选择?
好吧,显而易见的选择只是example作为普通参数传递而不是解压缩它:
def f(example):
pass
example = OrderedDict([('a', 1), ('b', 2)])
f(example)
Run Code Online (Sandbox Code Playgroud)
或者,当然,您可以使用*args并将项目作为元组传递,但这通常更加丑陋.
从PEP链接的线程中可能还有其他一些解决方法,但实际上,它们都不会比这更好.(除了...... IIRC,李浩义想出了一个基于他的MacroPy的解决方案来传递保留关键字的参数,但我不记得细节了.如果你愿意使用MacroPy并编写代码,MacroPy解决方案一般都很棒这听起来不像Python,但这并不总是合适的......)
dam*_*mio 17
Python 3.6.0a4+ (default:d43f819caea7, Sep 8 2016, 13:05:34)
>>> def func(**kw): print(kw.keys())
...
>>> func(a=1, b=2, c=3, d=4, e=5)
dict_keys(['a', 'b', 'c', 'd', 'e']) # expected order
Run Code Online (Sandbox Code Playgroud)
如其他答案所述,之前不可能这样做.