Enums with numeric names

Question:

The following doesn’t work in Python:

class MemorySize(int, Enum):
    "1024" = 1024
    "2048" = 2048

So what would be the closest way to do this without having to type the entire number out in words and make it type safe?

Asked By: basickarl

||

Answers:

From docs:

An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.

So, enum members should be symbolic names, not string literals.

If you want to use numbers as names you can prefix it with _ or m_, because private attributes start with underscore

Also, you can use IntEnum for integer enums.

from enum import IntEnum


class MemorySize(IntEnum):
    m_1024 = 1024
    m_2048 = 2048

print(MemorySize.m_1024.value)

Output

1024

Also, you can omit comma here "1024" = 1024,.

Actually 1024, is a tuple with one element (1024, ) and 1024 is just int. I was just curious, why you can pass tuple as well as int to Enum attribute.

I found out that the value of IntEnum attribute passes to int constructor. Before that it transforms args into tuple in EnumMeta.__new__

if not isinstance(value, tuple):
    args = (value, )
else:
    args = value

You can pass to int constructor second argument, the base:
because int("ff", 16) == 255. Or just use string constant instead of int because int("123") == 123.

So, you can use IntEnum values with any number system like this (Although I don’t think it’s good way to use it in practice)

class WeiredEnum(IntEnum):
    m_255 = "ff", 16
    m_256 = "256"

print(WeiredEnum.m_255.value)
print(type(WeiredEnum.m_256.value))
> 255
> <class 'int'>
Answered By: Yevhen Bondar

Don’t do that!

I was thinking of having an enum where I passed 1,2 instead of ONE, TWO, … since in my context there was no description it was just the number of an option returning a numeric value.

Analyzing it, I realized that in this case it actually doesn’t make sense to have an enum. If you have an enum of an integer that receives integer it is better not to have the enum at all and work only with the integer values, defining only the typing to limit it.

You can use the Literal type that was introduced in PEP 586 as a way to indicate that a variable must have a set of certain values.

from typing import Literal
ex: StatusCode = Literal[404, 200, 500]
Answered By: Mithsew
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.