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?
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'>
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]
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?
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'>
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]