覆盖枚举元类初始化
虽然pylint的提高上enum.Enum(value=..., names=...)
警告,我从枚举DOC看到一个可以以编程方式创建一个枚举像下面覆盖枚举元类初始化
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))
我认为这应该涉及重载metaclass __prepare__(mcls, names, bases)
以扩大基地的名称字典,但显然基地不是如何创建枚举属性。任何人有任何提示?
它使用aenum library
很简单:
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
。
披露:我是Python stdlib Enum
的作者,enum34
backport和Advanced Enumeration (aenum
)库。
感谢这是我正在寻找的东西。如果你有什么好的参考链接或者如何工作,我会很感激的;我试图更好地理解metaclass如何在底层工作,并且适用于我当前的项目(例如,在实例化过程中插入特定操作系统代码的标准化接口/协议类) –
如果您改为创建Enum
的新子类,该怎么办?
from enum import Enum
class ValidEnum(Enum):
@classmethod
def valid_rate(cls, value):
return (any(value == item.value for item in cls))
或者,根据用例,您可以创建另一个包装enum的类。
要么应该工作如下:
In [3]: BAUD_RATES = ValidEnum("BAUD_RATES", termios_baud_rates())
In [7]: BAUD_RATES.valid_rate(0)
Out[7]: True
In [11]: BAUD_RATES.valid_rate(213)
Out[11]: False
希望这有助于!
@Icary谢谢你的例子;我希望只是重写元类中的'__prepare__'或'__new__',因为这是需要它们的东西,即改变Enum在到达类__new__或__init__之前的构造方式。 –
更合理!我不确定这个问题入门级的问题,但听起来像是比简单的子类复杂一点,在这种情况下,'aenum'库看起来就像是要走的路。 – lcary
您还可以使用nonlocal
避免需要的aenum
包:
import re
import enum
import termios
regexp = r"(?:^|,)B(?P<rate>\d+)"
rates = sorted(map(int, re.findall(regexp, ",".join(dir(termios)))))
value = None
class BaudRate(enum.Enum):
nonlocal value
for value in rates:
locals()['B%d' % value] = value
@classmethod
def valid_rate(cls, value):
return (any(value == item.value for item in cls))
子类枚举:https://docs.python.org/3/library/enum.html#restricted-subclassing-of-enumerations – slezica