Jonathanthesailor
Jonathanthesailor

Reputation: 181

attributes of attributes of Enums?

I'm not sure, if something like this is possible, but I would like to save more attributes to enum attributes (like value).

Example:

class Unit(Enum):
    mm = "millimeter"

Unit.mm.value would return "millimeter".

Now I would like to access a short version, it would be awesome, if I could implement something, that results in Unit.mm.upper_case returning "Millimeter".

I know I could create an extra function, that takes Unit.mm as an attribute, and returns the desired output, but I'm sure there is a better way.

Upvotes: 2

Views: 146

Answers (2)

Jacques Gaudin
Jacques Gaudin

Reputation: 17008

You can define an additional property on an Enum member like so:

from enum import Enum

class Unit(Enum):
    mm = 'millimeter'

    @property
    def capitalized(self):
        # self is the member here, e.g. Unit.mm
        return self.value.capitalize()

print(Unit.mm.capitalized)

>>>Millimeter

Here is the docs reference.

Upvotes: 2

Shabble
Shabble

Reputation: 592

if you can derive the additional info purely from the name and value parts of your enum definition, you can use the property or method approach from Jacques above.

There's a second example in the enum module docs that describes how to override the __new__ method to attach additional info to each enum member, without impacting the ability to use Unit.mm.value to fetch the definition.

>>> class Coordinate(bytes, Enum):
...     """
...     Coordinate with binary codes that can be indexed by the int code.
...     """
...     def __new__(cls, value, label, unit):
...         obj = bytes.__new__(cls, [value])
...         obj._value_ = value
...         obj.label = label
...         obj.unit = unit
...         return obj
...     PX = (0, 'P.X', 'km')
...     PY = (1, 'P.Y', 'km')
...     VX = (2, 'V.X', 'km/s')
...     VY = (3, 'V.Y', 'km/s')
...

>>> print(Coordinate['PY'])
Coordinate.PY

>>> print(Coordinate(3))
Coordinate.VY

>>> print(Coordinate.VY.value)
3

>>> print(Coordinate.VY.unit)
km/s

Upvotes: 2

Related Questions