I have a simple Python 2.7 enum:
from enum import Enum
class Label(enum):
RedApple = 1
GreenApple = 2
I would like to be able create enum objects using case-insensitive keys:
fruitname = "redapple"
a = Label[fruitname]
I've tried to create an __init__
method:
def __init__(self, key):
super(Label, self).__init__()
pass # do comparison here
but I keep running into errors:
super(Label, self).__init__()
NameError: global name 'Label' is not defined
I'd like to do a comparison on key.lower().strip()
. Is this even possible?
I'm also a fan of simple things – and believe it's simpler in implementation to say enum values are case-insensitive, that implementations will always naturally produce values in uppercase, than it is to special-case handling in all languages that the deserialized values are uppercase, and may fill an UNKNOWN value.
Java conventions are that enum names are all uppercase, which immediately causes problems if you want to serialize the enum in another form. But when you serialize those enum values, you want to use lowercase values of "left", "top", "right", and "bottom". No problem—you can override Side.
Because they are constants, the names of an enum type's fields are in uppercase letters. You should use enum types any time you need to represent a fixed set of constants.
valueOf method is case-sensitive and invalid String will result in IllegalArgumentException. In short, The string passed to the valueOf method of Java enum must be the same as the String returned by name() method like TrafficSigal.RED.name() returns RED and you should pass RED to valueOf() to get TrafficSignal.
enum have missing function which can be overridden to make enum case insensitive. As per documentation https://docs.python.org/3.11/howto/enum.html missing – a lookup function used when a value is not found; may be overridden
example
class Status(enum.Enum):
@classmethod
def _missing_(cls, value):
for member in cls:
if member.value == value.upper():
return member
SUCCESS = 'SUCCESS'
FAILURE = 'FAILURE'
print(Status('success'))
Output
Status.SUCCESS
Not 100% sure this will work in Python 2.7, but I came up with a simple way to make it work exactly as requested for Python 3.6+.
The idea is that lookup for names is done by the class using square brackets, which means that it uses __getitem__
from the metaclass. So you can make a simple metaclass that implements a case insensitive search. Since it will extend the existing EnumMeta
, it will be totally compatible with existing enums:
class CaseInsensitiveEnumMeta(EnumMeta):
def __getitem__(self, item):
if isinstance(item, str):
item = item.upper()
return super().__getitem__(item)
This presupposes that your enums are all uppercase. Using it is pretty straightforward:
class Label(Enum, metaclass=CaseInsensitiveEnumMeta):
REDAPPLE = 1
GREENAPPLE = 2
I'm not sure you even need Enum
in this case. The catch here is that your enums have to be all uppercase for this to work. If you want to have a truly insensitive search, you would have to make sure that all of the keys in __members__
are properly casefolded.
In the meantime, you can do
>>> Label['GreenApple']
Label.GREENAPPLE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With