覆盖Enum元类初始化

时间:2017-10-16 21:10:26

标签: python enums

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

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)以使用名称dict扩充基础,但显然基础不是如何创建Enum属性。有人有任何提示吗?

3 个答案:

答案 0 :(得分:3)

使用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 Enumenum34 backportAdvanced Enumeration (aenum)图书馆的作者。

答案 1 :(得分:1)

如果您创建Enum的新子类,该怎么办?

from enum import Enum

class ValidEnum(Enum):

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

或者,根据用例,您可以创建另一个包装枚举的类。

要么应该如下工作:

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

希望这有帮助!

答案 2 :(得分:1)

您还可以使用$stu_ids=array_column($array1,'stu_id'); foreach($array2 as $row){ if(!in_array($row['stu_id'],$stu_ids)){ $result[]=$row; // auto-index the qualifying subarrays } } var_export($result); // same result as above method 来避免需要nonlocal包:

aenum