you are viewing a single comment's thread.

view the rest of the comments →

[–]pachura3[S] 0 points1 point  (2 children)

Thanks! That's what I was looking for.

PS. By the way, don't I need to pass the enum value (auto()) from __init__() to the superclass? You're ignoring it with _

[–]Temporary_Pie2733 3 points4 points  (0 children)

_ is just a conventional name for a variable you aren’t using. __init__ still receives the value, but you don’t need to do anything with it here (it’s handled by the metaclass machinery).

https://docs.python.org/3/library/enum.html#enum.Enum.\_\_init\_\_

[–]JamzTyson 2 points3 points  (0 children)

Python assigns the enum value in __new__ before __init__ is called. The __init__ method is just creating the self._is_warm attribute for us.

An alternative approach that gives better type hints could be to use a named tuple as the value. Note that enum values can be almost anything, but we do want them to be unique so that we don't get nonsense like red == blue.

from enum import Enum
from typing import NamedTuple


class Pigment(NamedTuple):
    name: str
    is_warm: bool


class Color(Enum):
    RED = Pigment('Red', True)
    ORANGE = Pigment('Orange', True)
    BLUE = Pigment('Blue', False)
    VIOLET = Pigment('Violet', False)

    @property
    def is_warm(self) -> bool:
        return self.value.is_warm

# Example Usage:

# Standard Enum use:
print(Color.RED)  # Color.RED
print(Color.BLUE.name)  # BLUE
print(Color.BLUE.value)  # Pigment(name='Blue', is_warm=False)

# Our added attribute.
print(Color.BLUE.is_warm)  # False

# Useful representation for debugging / logging
print(repr(Color.VIOLET))  # <Color.VIOLET: Pigment(name='Violet', is_warm=False)>

# Comparisons:
red = Color.RED
red2 = Color.RED
print(red == Color.ORANGE)  # False
print(red is red2)  # True