Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to use Python Enum or Dictionary for mapping constants and staying DRY with inference

I just started using Python for server-side programming (coming from TypeScript) and the verbosity of typing .value for an Enum is making me consider not using it at all.

In TypeScript the value of an Enum is retrieved like so..

enum CompassDirection {
  North = "North",
}

// I do not have to ask for the value
const isEqual = CompassDirection.North === "North" ? true : false

console.log(isEqual) // returns true 

But in Python I believe the only way to retrieve the value is using .value like so..

from enum import Enum

class CompassDirection(Enum):
    NORTH = 'NORTH'

isEqual = CompassDirection.NORTH == 'NORTH'
print(isEqual) // false

isEqual = CompassDirection.NORTH.value == 'NORTH'
print(isEqual) // true

My purpose of using Enum was for inference and so I wouldn't have to repeatedly type strings such as "NORTH" all in my code.

If I made a function I would have to call it everywhere as well - e.g.


def get_enum_value(enum): 
   return enum.value

# Calling this every time I want to use the enum.
get_enum_value(CompassDirection.NORTH)
get_enum_value(XEnum.Value)
get_enum_value(YEnum.Value)

Yet if I do not do this, this I'm repeatedly typing .value everywhere, which I'm finding counter-intuitive maybe because of my TypeScript bias.

Is there a way I can use Enum or a Dictionary achieve the inference that I want, keep my code as DRY as possible so I can avoiding typing my strings?

Note:

I don't mind making a few constants but I could see my imports getting lengthy for code-splitting / re-use.

Am I missing something? I'd like to understand this as soon as possible.

like image 756
A Webb Avatar asked Nov 01 '25 05:11

A Webb


1 Answers

The immediate solution to your problem is to inherit from str as well as from Enum1:

class CompassDirection(str, Enum):
    NORTH = 'NORTH'

>>> print(CompassDirection.NORTH == 'NORTH')
True

The long-term solution is to realize that you should no longer be using strings, but the enum members, and using is:

somevar = CompassDirections.NORTH
#
# some intervening code
#
print(somevar is CompassDirections.NORTH)
# True

You should only have to deal with the string "NORTH" if getting input from a user, a configuration file, etc., and then you'll want to immediately convert to an Enum:

result = input('Enter direction')
result = CompassDirection(result.upper())

1 Python 3.11 will have a StrEnum type, which will ensure that the values are already of type str.


Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

like image 186
Ethan Furman Avatar answered Nov 03 '25 17:11

Ethan Furman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!