繁体   English   中英

使用对象(例如,枚举)作为** kwargs中的键?

[英]Use an object (e.g., an Enum) as a key in **kwargs?

来自Python新手的一个非常简单的问题:

我的理解是,字典中的键几乎可以是任何不可变的数据类型。 是否可以将不可变的对象(例如,枚举类的成员)作为** kwargs词典中的键传递给函数或类? 我已经尝试过了,答案似乎是“否”:

from enum import Enum
class MyEnum(Enum):
    X= 'X'
    Y= 'Y'
def func(*args,**kwargs):
    pass
func(MyEnum.X = 1)

输出:

"SyntaxError: keyword can't be an expression"

但是,可能有些我想念的东西。

编辑:请注意,我不是在尝试使键等于MyEnum.X.value (在这种情况下为字符串); 我希望键是实际的Enum对象,例如MyEnum.X

你在做:

func(MyEnum.X = 1)

在这里,问题是MyEnum.X = 1您的关键字( MyEnum.X )实际上是一个表达式( getattr(MyEnum, 'X') ),表达式不能用作函数调用中的关键字。 实际上,只有标识符可以用作关键字。

为了开始工作,您需要使用字典解压缩,如下所示:

func(**{MyEnum.X.name: 1})

注意,要获取属性的名称,我需要执行MyEnum.X.nameMyEnum.X.value ,具体取决于您如何设置枚举-在您的情况下,它们是同一件事。

>>> from enum import Enum
>>> class Foo(Enum):
...   X = 'X'
... 
>>> Foo.X.value
'X'
>>> Foo.X.name
'X'

由于关键字参数的处理方式,这将不起作用。 该文件说:

[...]接下来,对于每个关键字参数,使用标识符来确定相应的槽(如果标识符与第一个形式参数名称相同,则使用第一个槽,依此类推)[...]

因此,必须有一种方法可以将字典中的键与形式参数名称进行匹配。 例外:

关键字必须是字符串

当您尝试传递非字符串的内容时:

func(**{MyEnum.X: 1})

建议需要最简单的情况:键必须是字符串。

一种可能的解决方法是使隐式的事情变得明确:只需创建一个类,其中包含要传递给属性并传递的所有必要信息。 该代码肯定会更具可读性。

我最初的问题的答案确实是“否”。 但是,由于有了mgilson和BartoszKP等人的投入,我提出的以下解决方案并不是一个不错的解决方案,并且可以解决当前的问题。 我将其提供给其他用户,以供其查看尝试进行类似操作的人员:

from enum import Enum
class MyEnum(Enum):
    X= 'X'
    Y= 'Y'

def func(*args,**kwargs):
    #replace kwargs with kwargsNew
    kwargsNew = {}
    for kwkey, kwvalue in kwargs.items():
        try: kwargsNew[MyEnum(kwkey)] = kwvalue
        except ValueError: kwargsNew[kwkey] = kwvalue
    doStuffWithKwargs(kwargsNew)

def doStuffWithKwargs(k):
    for K in k:
        print(K)

#Pass the name X or Y as the key; 
#all other keys not found in `MyEnum` are treated normally
func(X = 1, Y = 2, Z = 3)

输出:

Z
MyEnum.X
MyEnum.Y

(没有错误)

我发现的另一种选择是将字典传递给*args而不是**kwargs ,或者直接将字典分配给kwargs[0]

func({MyEnum.X: 1})
func(kwargs = {MyEnum.X: 1})

(无错误产生)

但是,我真的不喜欢这两种方法。

编辑:请参阅第二个答案,以获得更好的解决方案。

您是否真的想创建一个MyEnum实例?

 myenum = MyEnum()
 func(myenum.X = 1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM