Python枚举:用`element.value`替换`element`

时间:2019-06-24 18:00:35

标签: python enums

我有一个简单的Enum

class E(Enum):
    A = 'a'
    B = 'b'

要访问'a',我必须输入E.A.value。但是,value是我从枚举对象中唯一需要的东西。

如何编写一个枚举,'a'可以只访问E.A

2 个答案:

答案 0 :(得分:2)

  

将int用作值只是一个示例。它实际上应该是用户定义的类。

如果您将类/类型与Enum混合在一起,则只需访问成员本身,您将获得该类型的子类型:

from enum import Enum

class MyClass:
    def __init__(self, color):
        self.color = color

class MyEnum(MyClass, Enum):
    first = 'red'
    second = 'green'
    third = 'blue'

并在使用中:

>>> MyEnum.first
<MyEnum.first: 'red'>

>>> MyEnum.first.color
'red'

>>> type(MyEnum.first)
<enum 'MyEnum'>

>>> isinstance(MyEnum.first, MyClass)
True

披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum)库的作者。

答案 1 :(得分:1)

我四处张望,使用您尝试使用的Enum类找不到解决此问题的好的方法。但是,如果您不愿使用Enum作为超类的想法,则可以将其合并在一起:

class Demo:
    # something with a 'value' method in it
    def __init__(self, val):
        self.value = val

def custom_enum(cls):
    # class decorator to get __getattribute__() to work properly
    # this is necessary because __getattribute__() only exists as an instance method,
    #   and there seems to be no direct equivalent for class methods
    return cls()

@custom_enum
class E:
    # first, define our enumerated variables in a dict
    _enums = {
        'A': Demo('a'),
        'B': Demo('b'),
        'chicken': Demo('cluck')
    }

    # then, override __getattribute__() to first get the key from the dict, 
    #   and return the .value property of it
    def __getattribute__(self, key):
        # because of the decorator, we can't call self._enums or else we get a RecursionError
        # therefore, we need to implicitly subclass `object`, and then
        #   deliberately invoke object.__getattribute__ on self, to access _enums
        my_enums = object.__getattribute__(self, '_enums')
        return my_enums[key].value

实际上,定义可枚举的值就像编辑_enums字典一样简单。完成后,它应该可以按您希望的那样大致工作:

>>> E.A
'a'
>>> E.B
'b'
>>> E.chicken
'cluck'

您可以在此处根据需要修改实现(例如,返回AttributeError而不是KeyError,或者重写__setattr__()以使枚举值不可设置,或者等等)。