I have a class that is defined by a restricted set of values. Its instances need to be comparable to other instances of the class, but I want to be very explicit about which values it can take on. I initially defined these in a dictionary but then came across enums and prefer this option because just dumping everything in a dict at the top of the module looked a bit bad.
However I am having a problem with the enums now. I want them to be rank ordered so that I can carry out operations on instances of the class, like comparing to other instances. But I also want to have a "human readable" representation, and the class itself needs to be instantiated EITHER based on the values of those enums or as a combination of the abbreviations. What I have at the moment feels like a complete spaghetti:
class Day(IntEnum):
MONDAY = 1 # mon
TUESDAY = 2 # tue
WEDNESDAY = 3 # wed
class DayAbbrev(Enum):
MONDAY = 'mon'
TUESDAY = 'tue'
WEDNESDAY = 'wed'
class DayWeather(Enum):
RAIN = 'rainy'
SUN = 'sunny'
class SomeDay:
def __init__(self, abbrev=None, day=None, weather=None):
self.day = day or Day[DayAbbrev(abbrev.split('-')[1]).name].value
self.weather = weather or DayWeather(abbrev.split('-')[0]).value
self.abbrev = abbrev or '-'.join([DayWeather(weather).value, DayAbbrev[Day(1).name].value]) # e.g. sunny-mon, rainy-tue
sunnymon = SomeDay(day=1, weather='sunny') # Define based on ONLY valid enum values
rainytue = SomeDay('rainy-tue') # Define based on human-readable
In short, I don't want to use dictionaries because it feels suboptimal compared to enum classes. But the Day
enum should have both rank (integer) AND a human readable string representation. I could only accomplish this by creating a "helper" enum class (DayAbbrev), to help build this representation.
I saw a way to add attributes to enums, but I'm overall a bit unsure if this is appropriate for my needs, and it also adds more spaghetti when trying to access enum values/names. Am I misusing enums? If not, is there a better way to accomplish what I'm trying? Is the linked post what I should do here?