Это расширенное поведение, которое не понадобится в 90 +% от созданных перечислений.
Согласно документации:
The rules for what is allowed are as follows: _sunder_
names (starting and ending with a single underscore) are reserved by enum and cannot be used; all other attributes defined within an enumeration will become members of this enumeration, with the exception of __dunder__
names and descriptors
(methods are also descriptors).
Так что, если вы хотите постоянный класс у вас есть несколько вариантов:
- создать в
__init__
- добавить его после того, как класс был создан
- использовать миксин
- создать собственный
descriptor
Создание константы в __init__
и добавление ее после создания класса страдают от отсутствия всей информации о классе, собранной в одном месте.
Примеси, безусловно, могут быть использованы при необходимости (see dnozay's answer for a good example), но этот случай также может быть упрощена путем иметь базовый 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
Если вам действительно нужно, чтобы быть постоянным (он же не rebindable), а затем использовать new aenum library [1], которая будет блокировать попытки перераспределить constant
s, а также Enum
членов.
[1] aenum
написана автором enum34
.
В чем проблема с константой на уровне модуля? – delnan
@ delnan иногда константа специфична для класса. –
Я знаю, что пример из официальных документов, но действительно ли это хорошая идея? Это может быть отношение 'has-a' вместо' is-a'. –