首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >命名参数可以与Python枚举一起使用吗?

命名参数可以与Python枚举一起使用吗?
EN

Stack Overflow用户
提问于 2014-11-02 02:42:04
回答 3查看 2.1K关注 0票数 21

示例:

代码语言:javascript
复制
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),那么最好使用命名参数。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-03 03:52:45

虽然您不能像使用枚举描述的那样使用命名参数,但是您可以使用namedtuple混合来获得类似的效果:

代码语言:javascript
复制
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__方法。

示例用法:

代码语言:javascript
复制
>>> 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本身之前”。

票数 29
EN

Stack Overflow用户

发布于 2017-01-30 07:30:49

@zero-piraeus接受的答案可以稍微扩展一下,以允许默认参数。当您有一个很大的枚举,其中大多数条目对一个元素具有相同的值时,这是非常方便的。

代码语言:javascript
复制
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__,酸洗将无法工作。

代码语言:javascript
复制
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
票数 13
EN

Stack Overflow用户

发布于 2018-10-02 16:17:31

对于Python 3.6.1+,可以使用typing.NamedTuple,它还允许设置默认值,这会产生更漂亮的代码。然后,@shao.lo的示例如下所示:

代码语言:javascript
复制
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启发了这个解决方案。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26691784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档