Skip to main content
 首页 » 编程设计

python之覆盖枚举元类初始化

2025年05月04日14findumars

尽管 pylint 在 enum.Enum(value=..., names=...) 上发出警告,但我从枚举文档中看到可以通过编程方式创建如下所示的枚举

import re 
import enum 
import termios 
 
def termios_baud_rates(): 
    regexp = r"(?:^|,)B(?P<rate>\d+)" 
    rates = sorted(map(int, re.findall(regexp, ",".join(dir(termios))))) 
    return {"B{:d}".format(r): r for r in rates} 
 
BAUD_RATES = enum.Enum("BAUD_RATES", termios_baud_rates()) 

但我还想添加方法:

@classmethod 
def valid_rate(cls, value): 
    return (any(value == item.value for item in cls)) 

我认为这应该涉及重载元类 __prepare__(mcls, names, bases) 以使用 names dict 扩充 bases,但显然 bases 不是 Enum 属性的创建方式。有人有什么建议吗?

请您参考如下方法:

使用 aenum library 非常简单1:

import re 
import aenum 
import termios 
 
class BaudRate(aenum.Enum): 
    _ignore_ = 'cls regexp rates' 
 
    cls = vars() 
    regexp = r"(?:^|,)B(?P<rate>\d+)" 
    rates = sorted(map(int, re.findall(regexp, ",".join(dir(termios))))) 
    for value in rates: 
        cls['B%d' % value] = value 
 
    @classmethod 
    def valid_rate(cls, value): 
        return (any(value == item.value for item in cls)) 

_ignore_告诉aenum什么,嗯,忽略,事实上,_ignore_ 中的任何内容从最后的 Enum 中删除类。

由于 bug in Python's Enum除非你使用 aenum,否则这还行不通.


1 披露:我是 Python stdlib Enum 的作者, enum34 backport , 和 Advanced Enumeration ( aenum )图书馆。