如何在python 3枚举类中定义不是枚举值的属性?

How do define an attribute in Python 3 enum class that is NOT an enum value?

本问题已经有最佳答案,请猛点这里访问。

如何在不是枚举值的python 3枚举类中定义属性?

1
2
3
4
5
6
class Color(Enum):
    red = 0
    blue = 1
    violet = 2
    foo = 'this is a regular attribute'
    bar = 55  # this is also a regular attribute

但这对我来说似乎失败了。似乎color试图将foo和bar作为枚举值的一部分。

编辑:以免你认为我没有按照预期的方式使用枚举…例如,以官方的python文档的示例enum class planet(docs.python.org/3/library/enum.html planet)为例。注意,它们在surface_gravity()方法中定义了重力常数g。但这是奇怪的代码。一个普通的程序员会说,在函数之外设置一次常数g。但是,如果我尝试将g移出(但不移到全局范围,只移到类范围),那么我会遇到我在这里要问的问题。


在构建enum.Enum类时,所有常规属性都成为枚举的成员。不同类型的值没有区别。

通过常规属性,我指的是所有不是描述符(比如函数)和排除名称(使用单下划线名称,请参阅允许的成员和枚举属性部分)的对象。

如果在最终的enum.Enum对象上需要附加属性,请在后面添加属性:

1
2
3
4
5
6
7
class Color(Enum):
    red = 0
    blue = 1
    violet = 2

Color.foo = 'this is a regular attribute'
Color.bar = 55

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> from enum import Enum
>>> class Color(Enum):
...     red = 0
...     blue = 1
...     violet = 2
...
>>> Color.foo = 'this is a regular attribute'
>>> Color.bar = 55
>>> Color.foo
'this is a regular attribute'
>>> Color.bar
55
>>> Color.red
<Color.red: 0>
>>> list(Color)
[<Color.red: 0>, <Color.blue: 1>, <Color.violet: 2>]


Enum类型的要点是定义枚举值,因此非枚举值理论上超出了此类型的范围。对于常量,您无论如何都应该考虑将它们移出类型:它们可能与枚举值没有直接关系(而是建立在这些值之上的一些逻辑),并且应该是该类型的可变属性。通常,您只需要在模块级别创建一个常量。

如果您确实需要该类型上的某些内容,那么可以将其添加为类方法:

1
2
3
4
5
6
7
8
9
class Color(Enum):
    red = 0
    blue = 1
    violet = 2
    bar = 55

    @classmethod
    def foo (cls):
        return 'this is a not really an attribute…'

使用这个答案中的classproperty描述符,您还可以将它转换为类级别的属性,您可以像访问普通属性一样访问它:

1
2
3
4
5
6
7
8
9
class Color(enum.Enum):
    red = 0
    blue = 1
    violet = 2
    bar = 55

    @classproperty
    def foo (cls):
        return 'this is a almost a real attribute'
1
2
3
4
>>> Color.foo
'this is a almost a real attribute'
>>> list(Color)
[<Color.red: 0>, <Color.blue: 1>, <Color.violet: 2>, <Color.bar: 55>]