You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否为自定义Python Enum传递关键字参数(kwargs)?

自定义Python Enum成员的关键字参数疑惑

问题背景

我们可以自定义Python Enum让成员拥有额外属性,常见写法如下:

class EnumWithAttrs(Enum):
    def __new__(cls, *args, **kwargs):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj
    def __init__(self, a, b):
        self.a = a
        self.b = b
    
    GREEN = 'a', 'b'
    BLUE = 'c', 'd'

多数示例中__new__方法声明接收**kwargs,但尝试通过类定义或函数式语法传递关键字参数时均触发语法错误:

类定义写法报错:

class EnumWithAttrs(Enum):
    GREEN = 'a', foo='b'
    BLUE = 'c', **{'bar':  'd'}

函数式写法也报错:

Color = EnumWithAttrs('Color', [('GREEN', 'a', foo='b'), ('BLUE', 'c', **{'bar': 'd'})])

请问开发者在__new__中声明**kwargs是出于习惯,还是存在合法使用方式?注:不接受将字典作为位置参数的替代方案。

解答

1. 常规写法无法传递关键字参数的原因

Python语法规则和Enum底层逻辑共同限制了参数传递方式:

  • 类定义中,GREEN = 'a', foo='b'属于非法表达式,逗号分隔的赋值右侧不能混合位置值和关键字参数语法。
  • 函数式创建Enum时,('GREEN', 'a', foo='b')同样违反元组语法,元组元素只能是具体值,不能包含关键字参数声明。
    Enum底层只会将成员赋值右侧的内容拆解为位置参数传递给__new__和__init__,没有处理关键字参数的入口。

2. __new__中声明**kwargs的主要原因

多数情况是编程习惯延续:

  • 防御性编程:开发者为兼容未来Enum底层可能的功能变化(比如官方新增关键字参数支持),提前预留参数位,避免后续大规模修改代码。
  • 通用构造方法模仿:很多类的__new__或__init__会添加**kwargs来接收未明确声明的额外参数,防止意外传入参数导致报错,这种写法被自然延续到了Enum自定义场景中。

3. 合法使用**kwargs的特殊场景

如果绕过常规Enum成员定义语法,通过手动创建并注册成员的方式,可以合法传递关键字参数。示例如下:

from enum import Enum

class EnumWithAttrs(Enum):
    def __new__(cls, *args, **kwargs):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        # 处理传入的关键字参数
        for key, val in kwargs.items():
            setattr(obj, key, val)
        return obj
    def __init__(self, a):
        self.a = a

# 手动创建成员并完成初始化
green_member = EnumWithAttrs.__new__(EnumWithAttrs, 'a', foo='b')
green_member.__init__('a')
# 将成员注册到Enum的成员映射字典中
EnumWithAttrs._member_map_['GREEN'] = green_member

这种方式避开了常规语法限制,能合法利用__new__中的**kwargs,但需要手动处理成员注册逻辑,仅适合特殊场景,不推荐作为常规写法。

内容的提问来源于stack exchange,提问作者mahkitah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 01:20:35