Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
命名参数可以与Python枚举一起使用吗?_Python_Python 3.x_Enums_Named Parameters - Fatal编程技术网

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

命名参数可以与Python枚举一起使用吗?,python,python-3.x,enums,named-parameters,Python,Python 3.x,Enums,Named Parameters,例如: 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 参考: 我为什么要这样做?如果构造函数列表中有一些基元类型(int、bool),最好使用命名

例如:

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
参考:


我为什么要这样做?如果构造函数列表中有一些基元类型(int、bool),最好使用命名参数。

虽然不能按照枚举描述的方式使用命名参数,但通过mixin可以获得类似的效果:

。。。在我看来,这更干净,因为您不必编写
\uuuu init\uuu
方法

示例用法:

>>> Planet.MERCURY
<Planet.MERCURY: Body(mass=3.303e+23, radius=2439700.0)>
>>> Planet.EARTH.mass
5.976e+24
>>> Planet.VENUS.radius
6051800.0
>Planet.MERCURY
>>>行星、地球、质量
5.976e+24
>>>行星。金星。半径
6051800

请注意,如所述,“混合类型必须按碱基顺序出现在
Enum
本身之前”。

可以稍微扩展@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)
注意,如果没有
\uu getnewargs\uu
,酸洗将不起作用

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

如果超出了
namedtuple
mix的范围,请查看图书馆1。除了为
Enum
提供一些额外的提示外,它还支持
NamedConstant
和基于元类的
NamedTuple

使用
aenum.Enum
上述代码可能如下所示:

from aenum import Enum, enum, _reduce_ex_by_name

class Planet(Enum, init='mass radius'):
    MERCURY = enum(mass=3.303e+23, radius=2.4397e6)
    VENUS   = enum(mass=4.869e+24, radius=6.0518e6)
    EARTH   = enum(mass=5.976e+24, radius=3.3972e6)
    # replace __reduce_ex__ so pickling works
    __reduce_ex__ = _reduce_ex_by_name
在使用中:

--> for p in Planet:
...     print(repr(p))
<Planet.MERCURY: enum(radius=2439700.0, mass=3.3030000000000001e+23)>
<Planet.EARTH: enum(radius=3397200.0, mass=5.9760000000000004e+24)>
<Planet.VENUS: enum(radius=6051800.0, mass=4.8690000000000001e+24)>

--> print(Planet.VENUS.mass)
4.869e+24
-->对于行星中的p:
...     打印(报告(p))
-->打印(行星、金星、质量)
4.869e+24

1披露:我是、和库的作者。

对于Python 3.6.1+可以使用,它还允许设置默认值,从而生成更漂亮的代码。@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)
这也支持酸洗。如果不想指定类型,可以使用Any


归功于@monk time,他的答案启发了这个解决方案。

非常酷。我从来没有考虑过用混音器来解决这个问题。@ZeroPiraeus:我添加了一个答案,但不是为了赏金——只是希望获得一些选票(我的[python-3.x]金徽章还有很长的路要走!;)@ZeroPiraeus谢谢你,先生!
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)