如何在 Python 枚举的 __new__ 中实现自动整数值分配并扩展属性-Python教程

本文详解如何在自定义 `enum` 子类中正确实现自动递增整数枚举值(类似 `auto()` 行为),同时为每个成员附加额外属性(如正则规则字符串),解决直接在 `__new__` 中调用 `auto()` 失败的问题。

在 Python 的 enum 模块中,auto() 是一个占位符对象,它仅在枚举类定义阶段被 EnumMeta 元类解析并替换为实际值,而非运行时可调用函数。因此,在 __new__ 方法内部直接写 auto()(如 member._value_ = auto())是无效的——此时 auto() 尚未被求值,且 __new__ 已处于成员实例化阶段,元类干预早已完成。

要实现“声明式赋值字符串、自动分配唯一整数 _value_、并保留原始字符串为自定义属性”的目标,核心思路是:手动模拟 auto() 的递增逻辑,并确保使用正确的基类构造方式。以下是推荐的完整实现方案:

✅ 正确做法:基于 IntEnum 的自动整数分配(推荐)

from enum import IntEnum

class TokenEnum(IntEnum):
    def __new__(cls, value):
        # 手动计算下一个整数值:从 1 开始递增(与 auto() 默认行为一致)
        int_value = len(cls.__members__) + 1
        # 关键:必须使用 int.__new__(cls, int_value) 构造整数实例
        member = int.__new__(cls, int_value)
        member._value_ = int_value  # 显式赋值(冗余但清晰)
        member.rule = value         # 保存原始字符串(如正则表达式)
        return member

# 使用示例
class Tokens(TokenEnum):
    ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    NUMBER = r'\d+'
    PLUS = r'\+'

# 验证结果
print(Tokens.ID)           # Tokens.ID
print(Tokens.ID.value)     # 1
print(Tokens.ID.rule)      # '[a-zA-Z_][a-zA-Z0-9_]*'
print(Tokens.NUMBER.value) # 2

⚠️ 注意事项:必须继承 IntEnum(而非 Enum 或 object),否则无法支持整数运算和比较;构造实例时务必调用 int.__new__(cls, int_value),而非 object.__new__(cls),否则会丢失 int 类型特性;len(cls.__members__) 在 __new__ 调用时已包含当前正在创建的成员?不,它只包含此前已成功创建的成员,因此 +1 是安全且准确的起始偏移。

? 替代方案:非整数枚举但 _value_ 仍为 int(兼容性更强)

若你不需要枚举成员本身是 int 实例(例如不参与算术运算),但希望 .value 返回整数、.name 和 .rule 保持分离,可改用 Enum 基类:

from enum import Enum

class TokenEnum(Enum):
    def __new__(cls, value):
        int_value = len(cls.__members__) + 1
        member = object.__new__(cls)  # 不依赖 int 构造
        member._value_ = int_value    # 但 _value_ 仍是 int
        member.rule = value
        return member

此时 Tokens.ID 是 TokenEnum 实例,Tokens.ID.value 为 1,Tokens.ID.rule 为正则字符串,语义更清晰,也避免了 IntEnum 的隐式类型约束。

立即学习“Python免费学习笔记(深入)”;

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » 如何在 Python 枚举的 __new__ 中实现自动整数值分配并扩展属性-Python教程
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1394+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4036664+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1394+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4036664+
  • 本周更新: 0+
  • 最后更新: 2026-03-16