示例:
class Planet(Enum):
MERCURY = (mass: 3.303e+23, radius: 2.4397e6)
def __init__(self, mass, radius):
self.mass = mass # in kilograms
self.radius = radius # in meters
参考:https://docs.python.org/3/library/enum.html#planet
我为什么要这样做?如果构造函数列表中有一些基本类型(int、bool),那么最好使用命名参数。
发布于 2014-11-03 03:52:45
虽然您不能像使用枚举描述的那样使用命名参数,但是您可以使用namedtuple
混合来获得类似的效果:
from collections import namedtuple
from enum import Enum
Body = namedtuple("Body", ["mass", "radius"])
class Planet(Body, Enum):
MERCURY = Body(mass=3.303e+23, radius=2.4397e6)
VENUS = Body(mass=4.869e+24, radius=6.0518e6)
EARTH = Body(mass=5.976e+24, radius=3.3972e6)
# ... etc.
..。在我看来,这更简洁,因为您不必编写__init__
方法。
示例用法:
>>> Planet.MERCURY
<Planet.MERCURY: Body(mass=3.303e+23, radius=2439700.0)>
>>> Planet.EARTH.mass
5.976e+24
>>> Planet.VENUS.radius
6051800.0
请注意,根据the docs,“混合类型必须出现在基础序列中的Enum
本身之前”。
发布于 2017-01-30 07:30:49
@zero-piraeus接受的答案可以稍微扩展一下,以允许默认参数。当您有一个很大的枚举,其中大多数条目对一个元素具有相同的值时,这是非常方便的。
class Body(namedtuple('Body', "mass radius moons")):
def __new__(cls, mass, radius, moons=0):
return super().__new__(cls, mass, radius, moons)
def __getnewargs__(self):
return (self.mass, self.radius, self.moons)
class Planet(Body, Enum):
MERCURY = Body(mass=3.303e+23, radius=2.4397e6)
VENUS = Body(mass=4.869e+24, radius=6.0518e6)
EARTH = Body(5.976e+24, 3.3972e6, moons=1)
请注意,如果没有__getnewargs__
,酸洗将无法工作。
class Foo:
def __init__(self):
self.planet = Planet.EARTH # pickle error in deepcopy
from copy import deepcopy
f1 = Foo()
f2 = deepcopy(f1) # pickle error here
发布于 2018-10-02 16:17:31
对于Python 3.6.1+,可以使用typing.NamedTuple,它还允许设置默认值,这会产生更漂亮的代码。然后,@shao.lo的示例如下所示:
from enum import Enum
from typing import NamedTuple
class Body(NamedTuple):
mass: float
radius: float
moons: int=0
class Planet(Body, Enum):
MERCURY = Body(mass=3.303e+23, radius=2.4397e6)
VENUS = Body(mass=4.869e+24, radius=6.0518e6)
EARTH = Body(5.976e+24, 3.3972e6, moons=1)
这也支持酸洗。如果您不想指定类型,可以使用typing.Any。
感谢@monk-time,谁的答案here启发了这个解决方案。
https://stackoverflow.com/questions/26691784
复制相似问题