Example:
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
Ref: https://docs.python.org/3/library/enum.html#planet
Why do I want to do this? If there are a few primitive types (int, bool) in the constructor list, it would be nice to used named arguments.
Customize Python enum classes Python enumerations are classes. It means that you can add methods to them, or implement the dunder methods to customize their behaviors.
By definition, the enumeration member values are unique. However, you can create different member names with the same values.
Enum is a class in python for creating enumerations, which are a set of symbolic names (members) bound to unique, constant values. The members of an enumeration can be compared by these symbolic anmes, and the enumeration itself can be iterated over.
By convention, enumeration names begin with an uppercase letter and are singular. The enum module is used for creating enumerations in Python.
While you can't use named arguments the way you describe with enums, you can get a similar effect with a namedtuple
mixin:
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.
... which to my mind is cleaner, since you don't have to write an __init__
method.
Example use:
>>> Planet.MERCURY <Planet.MERCURY: Body(mass=3.303e+23, radius=2439700.0)> >>> Planet.EARTH.mass 5.976e+24 >>> Planet.VENUS.radius 6051800.0
Note that, as per the docs, "mix-in types must appear before Enum
itself in the sequence of bases".
The accepted answer by @zero-piraeus can be slightly extended to allow default arguments as well. This is very handy when you have a large enum with most entries having the same value for an element.
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)
Beware pickling will not work without the __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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With