Search code examples
pythonpython-3.xenumsnamed-parameters

Can named arguments be used with Python enums?


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.


Solution

  • 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".