我们举个例子:

def fun(**args):
    print(str(args))

dic = {'name': 'Pulkit'}
fun(**dic)

此代码运行良好,我有以下输出:
{'name': 'Pulkit'}

现在让我们将值作为字节传递:
dic_vb = {'name': b'Pulkit'}
fun(**dic_vb)

这也可以正常工作,并具有以下输出:
{'name': b'Pulkit'}

但当我尝试将密钥作为字节时,情况会发生变化:
dic_kb = {b'name': 'Pulkit'}

这会导致输入错误:
TypeError: fun() keywords must be strings

有没有办法把字节作为关键字参数传递。我还检查了repo处的cpython代码,它处理关键字参数,似乎我们不能通过。有什么解决办法吗?或者我需要确保独角兽通过。
我正在处理一个代码库,其中我们在python 2上有很多这样的实例,需要移植到python 3。所以唯一可能的方法是将所有的关键字参数转换为unicodes?

最佳答案

不,关键字必须是有效的标识符,这与为什么不能为期望**kwargs的函数提供将数字作为键的字典相同:

>>> dic = {1: 'Pulkit'}
>>> fun(**dic)
TypeErrorTraceback (most recent call last)
<ipython-input-54-83c29ed0f08e> in <module>()
      3
      4 dic = {1: 'Pulkit'}
----> 5 fun(**dic)

TypeError: fun() keywords must be strings

这也是你在源代码中看到的,而!的否定(PyUnicode_Check)充当了执行者。
这是必需的;您需要提供能够充当名称的密钥。要查看什么是和什么是不允许的,只需尝试将其分配给交互式解释器中的一个名称,然后查看错误:
>>> b'my_list' = [...]  # err
>>> 23 = [21, 22]       # err

一个可行的(并且是唯一的,如果decode是不允许的)选项是将字典作为另一个参数传递,然后通过普通字典查找访问值。
当然,如果在调用函数之前将字节解码为字符串是一个可行的替代方案,我建议您采用该选项:
>>> dic = {b'name': 'Pulkit'}
>>> fun(**{b.decode(): v for b, v in dic.items()})

08-04 10:19
查看更多