这是一种高级行为,90% 以上的枚举都不需要。
根据文档:
允许的规则如下:_sunder_
名称(以单个下划线开头和结尾)由枚举保留,不能使用;枚举中定义的所有其他属性都将成为该枚举的成员,除了__dunder__
名称和descriptors
(方法也是描述符)。
所以如果你想要一个类常量,你有几个选择:
- 创建它
__init__
- 在创建类后添加它
- 使用混合
- 创建你自己的
descriptor
创建常量__init__
并在创建类后添加它都受到没有将所有类信息收集在一个地方的困扰。
在适当的时候当然可以使用 Mixins(参见 dnozay 的回答以获得一个很好的例子),但这种情况也可以通过使用Enum
内置实际常量的基类来简化。
首先,将在以下示例中使用的常量:
class Constant: # use Constant(object) if in Python 2
def __init__(self, value):
self.value = value
def __get__(self, *args):
return self.value
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.value)
以及一次性使用的枚举示例:
from enum import Enum
class Planet(Enum):
MERCURY = (3.303e+23, 2.4397e6)
VENUS = (4.869e+24, 6.0518e6)
EARTH = (5.976e+24, 6.37814e6)
MARS = (6.421e+23, 3.3972e6)
JUPITER = (1.9e+27, 7.1492e7)
SATURN = (5.688e+26, 6.0268e7)
URANUS = (8.686e+25, 2.5559e7)
NEPTUNE = (1.024e+26, 2.4746e7)
# universal gravitational constant
G = Constant(6.67300E-11)
def __init__(self, mass, radius):
self.mass = mass # in kilograms
self.radius = radius # in meters
@property
def surface_gravity(self):
return self.G * self.mass / (self.radius * self.radius)
print(Planet.__dict__['G']) # Constant(6.673e-11)
print(Planet.G) # 6.673e-11
print(Planet.NEPTUNE.G) # 6.673e-11
print(Planet.SATURN.surface_gravity) # 10.44978014597121
最后,多用途枚举示例:
from enum import Enum
class AstronomicalObject(Enum):
# universal gravitational constant
G = Constant(6.67300E-11)
def __init__(self, mass, radius):
self.mass = mass
self.radius = radius
@property
def surface_gravity(self):
return self.G * self.mass / (self.radius * self.radius)
class Planet(AstronomicalObject):
MERCURY = (3.303e+23, 2.4397e6)
VENUS = (4.869e+24, 6.0518e6)
EARTH = (5.976e+24, 6.37814e6)
MARS = (6.421e+23, 3.3972e6)
JUPITER = (1.9e+27, 7.1492e7)
SATURN = (5.688e+26, 6.0268e7)
URANUS = (8.686e+25, 2.5559e7)
NEPTUNE = (1.024e+26, 2.4746e7)
class Asteroid(AstronomicalObject):
CERES = (9.4e+20 , 4.75e+5)
PALLAS = (2.068e+20, 2.72e+5)
JUNOS = (2.82e+19, 2.29e+5)
VESTA = (2.632e+20 ,2.62e+5
Planet.MERCURY.surface_gravity # 3.7030267229659395
Asteroid.CERES.surface_gravity # 0.27801085872576176
注意:
Constant
G
真的不是。一个人可以重新绑定G
到别的东西:
Planet.G = 1
如果你真的需要它保持不变(也就是不可重新绑定),那么使用新的 aenum 库[1] 它将阻止重新分配constant
s 以及Enum
成员的尝试。
1披露:我是Python stdlibEnum
、enum34
backport和Advanced Enumeration ( aenum
) 库的作者。