python - 在 **kwargs 中使用 OrderedDict

标签 python parameter-passing keyword-argument

是否可以将 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

但实际结果是:

>> second 2
>> third -1
>> first 1

即,典型的随机字典排序。

我还有其他用途可以明确设置顺序,所以我想保留 **kwargs 而不仅仅是将 OrderedDict 作为常规参数传递

最佳答案

从 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,不管关键字来自 哪里——显式关键字 args按照它们出现的顺序,然后是 **example 的所有项目,按照它们在 example 中出现的顺序(如果 example 是一个 dict,但如果它是一个 OrderedDict 也可能有意义)。

定义所有繁琐的细节并保持性能可接受,结果比听起来更难。见 PEP 468和链接的线程,用于讨论这个想法。这一次似乎停滞不前,但如果有人拿起它并支持它(并编写一个引用实现供人们使用 - 这取决于可从 C API 访问的 OrderedDict ,但是有望在 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 和编写的代码读起来不像 Python,但这并不总是合适的……)

关于python - 在 **kwargs 中使用 OrderedDict,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26748097/

相关文章:

python - 如何通过遍历 __init__ 参数来创建实例属性?

python - 数据类参数是否有别名或名称参数?

python - Curses 菜单模块有自己的方法

python - 为 Pandas 行中的逗号分隔字符串生成组合

python - numpy 数组大小的困惑

javafx - 传递参数JavaFX FXML

python - 有没有办法在 python 中删除列表?

c程序交换值打印错误结果

r - 仅当满足条件时函数的默认参数

python - 执行子函数的主函数