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

如何在Python3枚举类中定义不是枚举值的属性?,python,python-3.x,enums,Python,Python 3.x,Enums,如何在Python3枚举类中定义不是枚举值的属性 class Color(Enum): red = 0 blue = 1 violet = 2 foo = 'this is a regular attribute' bar = 55 # this is also a regular attribute 但这对我来说似乎失败了。颜色似乎试图将foo和bar作为枚举值的一部分 编辑: 以免您认为我没有以预期的方式使用Enum。。。例如,以Python官方文

如何在Python3枚举类中定义不是枚举值的属性

class Color(Enum):
    red = 0
    blue = 1
    violet = 2
    foo = 'this is a regular attribute'
    bar = 55  # this is also a regular attribute
但这对我来说似乎失败了。颜色似乎试图将foo和bar作为枚举值的一部分

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

枚举类型的要点是定义枚举值,因此非枚举值理论上不在该类型的范围内。对于常量,您应该考虑将它们移出类型:它们可能不直接与枚举值相关(而是建立在那些枚举值上的一些逻辑),并且也应该是类型的可变属性。通常,您只需在模块级别创建一个常量

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

class Color(Enum):
    red = 0
    blue = 1
    violet = 2
    bar = 55

    @classmethod
    def foo (cls):
        return 'this is a not really an attribute…'
使用中的
classproperty
描述符,还可以将其转换为类级别的属性,您可以像访问普通属性一样访问该属性:

class Color(enum.Enum):
    red = 0
    blue = 1
    violet = 2
    bar = 55

    @classproperty
    def foo (cls):
        return 'this is a almost a real attribute'
>>Color.foo
“这几乎是一个真实的属性”
>>>列表(颜色)
[, , ]

在构建
enum.enum
类时,所有常规属性都成为枚举的成员。不同类型的值不会产生差异

我所说的常规属性是指所有不是描述符(如函数)的对象和排除的名称(使用单下划线名称,请参阅)

如果在最终的
enum.enum
对象上需要其他属性,请在之后添加属性:

演示:

>>从枚举导入枚举
>>>类别颜色(枚举):
...     红色=0
...     蓝色=1
...     紫罗兰色=2
... 
>>>Color.foo='这是一个常规属性'
>>>Color.bar=55
>>>Color.foo
'这是一个常规属性'
>>>颜色栏
55
>>>颜色:红色
>>>列表(颜色)
[, ]

您为什么需要这个?你不能这样做,不。没有内置的工具可以将某些属性视为枚举,而将其他属性视为“常规”。就Python而言,枚举中的
foo
bar
之间没有区别。仅仅因为你对值使用了不同类型的对象没有什么区别。因为这些奇特的枚举类存在的原因之一是它们可以是常规类,你知道,有方法等等,最终,我需要一个类级常量@EthanFurman我真的不明白为什么你觉得有必要在结束问题5个月后再去看一个封闭的问题,再次明确地链接到你的答案(这也是关于封闭目标的公认答案),对这个封闭问题的两个答案进行否决,虽然这些答案可能有点复杂,但都能为问题提供有效的解决方案。您是否过于自信您的解决方案是满足此需求的唯一可接受的解决方案?@poke:我正在查看所有[enums][python]答案,并在适当的情况下进行上/下投票。我不同意您在此实例中对
Enum
数据类型的描述(在其他实例中,您的投票数比我高)。如果其他人编写了我的解决方案,我也会对这些答案/评论采取同样的行动。
Enum
元类确实通过描述符协议支持@eng的用例(换句话说,Python支持它,我不需要做任何额外的事)。@EthanFurman:是的,你必须创建一个描述符,在我的书中,这肯定是在做一些额外的事情。这是一个很好很聪明的把戏,但这并不意味着我的技术是错误的。我的答案真的那么没用,值得投反对票吗?啊,我的意思是,在创建元类来支持这个用例时,我不需要做任何额外的事情。由于在类创建后分配属性的丑恶做法和评论中的错误信息,我投了反对票。我希望总分为-1可以警告未来的求职者不要使用这些答案。@EthanFurman:我们可以很容易地清理这些评论;只要在你认为应该去的地方打个旗子就行了。它们不是答案的一部分。你在自己的回答中提到在类创建后分配属性作为解决方案。是的,我在回答中提到在类创建后分配属性;我还提到了为什么这不是一个好的解决方案。工作日很快就会变得非常繁忙。我已经不记得那句话的上下文了,5个月后我真的很难知道我在想什么……但我想我想说的是,当你有一个成员在类型对象上公开时,公共接口只是请求访问和修改它。对于常数来说,这不是一个好主意。常量应该在安全的地方,或者至少清楚地标记为常量。啊,这是有道理的。谢谢
>>> Color.foo
'this is a almost a real attribute'
>>> list(Color)
[<Color.red: 0>, <Color.blue: 1>, <Color.violet: 2>, <Color.bar: 55>]
class Color(Enum):
    red = 0
    blue = 1
    violet = 2

Color.foo = 'this is a regular attribute'
Color.bar = 55
>>> 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>]