Python枚举:将`element`替换为`element.value`

Python枚举:将`element`替换为`element.value`,python,enums,Python,Enums,我有一个简单的枚举: E类(枚举): A='A' B='B' 要访问'a'我必须键入E.a.value。但是,值是我从Enum对象需要的唯一东西 如何编写一个枚举,其中'a'仅通过E.a即可访问?我四处查看了很多,使用您尝试使用的Enum类找不到解决此问题的好方法。但是,如果您愿意避免使用Enum作为超类,您可以将其组合在一起: class Demo: # something with a 'value' method in it def __init__(self, val)

我有一个简单的
枚举

E类(枚举):
A='A'
B='B'
要访问
'a'
我必须键入
E.a.value
。但是,
是我从Enum对象需要的唯一东西


如何编写一个枚举,其中
'a'
仅通过
E.a
即可访问?

我四处查看了很多,使用您尝试使用的
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
实际上,定义可枚举项的值就像编辑
\u enums
dict一样简单。一旦这样做了,它应该可以按照您的要求大致工作:

>>> E.A
'a'
>>> E.B
'b'
>>> E.chicken
'cluck'
从这里,您可以根据需要修改实现(例如,返回
AttributeError
而不是
KeyError
,或者重写
\uuuuuu setattr\uuuuuuuu()
以使枚举值不可设置,等等)

使用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
>>MyEnum.first
>>>MyEnum.first.color
“红色”
>>>类型(MyEnum.first)
>>>iInstance(MyEnum.first,MyClass)
真的


披露:我是、和库的作者。

您可以使用
IntEnum
来完成。检查。@cs95谢谢!然而,使用
int
作为值只是一个例子。它实际上应该是一个用户定义的类。我将重写我的问题,你能删除
replicate
标志吗?你的意思是将
A
定义为
self.A='A'
等等?副本已更新。您需要使用
self
。除非您想使用
IntEnum
(除非您试图保持与
enum
模块之前编写的代码的兼容性,否则您确实不应该使用),否则您必须使用
元素.value
,这就是enum的工作方式。为什么在这里使用
enum
?看起来你可能想要别的东西。也许是一个X-Y问题,我发布了一个答案,说明了如何使用
Enum
实现这一点。