これは高度な動作であり、作成された列挙の 90% 以上では必要ありません。
ドキュメントによると:
許可されるもののルールは次のとおりです。_sunder_
名前 (単一のアンダースコアで開始および終了する) は列挙型によって予約されており、使用できません。__dunder__
列挙内で定義された他のすべての属性は、名前とdescriptors
(メソッドも記述子です)を除いて、この列挙のメンバーになります。
したがって、クラス定数が必要な場合は、いくつかの選択肢があります。
- で作成します
__init__
- クラスが作成された後に追加します
- ミックスインを使用する
- 自分で作る
descriptor
で定数を作成し__init__
、クラスが作成された後に追加すると、すべてのクラス情報が 1 か所に集められないという問題が生じます。
適切な場合はミックスインを使用できますが (良い例については 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)
そして、使い捨ての Enum の例:
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
最後に、多用途の Enum の例を示します。
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
) ライブラリの作成者です。