how to check if a variable is of type enum in python
Asked Answered
L

5

42

I have an enum like this

@enum.unique
class TransactionTypes(enum.IntEnum):
    authorisation = 1
    balance_adjustment = 2
    chargeback = 3
    auth_reversal = 4

Now i am assigning a variable with this enum like this

a = TransactionTypes

I want to check for the type of 'a' and do something if its an enum and something else, if its not an enum

I tried something like this

if type(a) == enum:
    print "do enum related stuff"
else:
    print "do something else"

The problem is it is not working fine.

Louanneloucks answered 15/7, 2016 at 10:32 Comment(2)
enum is the module, why would it be equal to type(TransactionTypes)? Do you want if issubclass(a, enum.Enum):?Clypeus
You could use members special attribute to iterate over membersShalom
I
78

Now i am assigning a variable with this enum like this

a = TransactionTypes

I hope you aren't, because what you just assigned to a is the entire enumeration, not one of its members (such as TransactionTypes.chargeback) If that is really what you wanted to do, then the correct test would be:

if issubclass(a, enum.Enum)

However, if you actually meant something like:

a = TransactionTypes.authorisation

then the test you need is:

# for any Enum member
if isinstance(a, Enum):

or

# for a TransactionTypes Enum
if isinstance(a, TransactionTypes):
Islamism answered 15/7, 2016 at 17:31 Comment(1)
Never mind what I said, it was just a logical error in my program.Lemley
A
2

as mentioned use isinstance method to check weather an instance is of enum.Enum type or not.

A small working code for demonstration of its usage:

import enum


class STATUS(enum.Enum):
    FINISHED = enum.auto()
    DELETED = enum.auto()
    CANCELLED = enum.auto()
    PENDING = enum.auto()


if __name__ == "__main__":
    instance = STATUS.CANCELLED

    if isinstance(instance, enum.Enum):
        print('name : ', instance.name, ' value : ', instance.value)
    else:
        print(str(instance))

Output:

name :  CANCELLED  value :  3
Andro answered 20/2, 2022 at 9:59 Comment(0)
C
0

reliable solution:

from enum import IntEnum
from collections import Iterable

def is_IntEnum(obj):
    try:
        return isinstance(obj, Iterable) and isinstance (next(iter(obj)), IntEnum)
    except:
        return False # Handle StopIteration, if obj has no elements
Clarendon answered 15/2, 2021 at 18:29 Comment(5)
What did you find unreliable about the accepted answer?Islamism
@EthanFurman from enum import IntEnum, Enum class MyEnum(IntEnum): FOO_BAR = 0 JOHN_DOE = 1 print( isinstance(MyEnum, Enum) ) # False print( isinstance(MyEnum, IntEnum) ) # FalseClarendon
You are using the wrong comparison: MyEnum is a type, and to check if one type is a subclass of another type you use issubclass; so your example should be issubclass(MyEnum, Enum) and issubclass(MyEnum, IntEnum), both of which would return True. isinstance would be appropriate for isinstance(MyEnum.JOHN_DOE, IntEnum).Islamism
Your answer uses issubclass which will raise an error on not a class object. List and enum are both iterables, both can be used as iterable list of choices for something. Therefore, your answer is not reliable solution. My answer may be not beatiful, but it is reliable. Thus your minus to me is not justified.Clarendon
In my experience using an isinstance() check with subclasses has always been an error: either issubclass() was the correct choice, or I was comparing the wrong objects. Your "reliable" method would hide those bugs. If you can add an example to your answer where either a list or an IntEnum member would be appropriate values, I will happily remove my downvote.Islamism
I
0

I thought I`ve got a ugly way. eg:

print(o.__class__.__class__) 

Output:

<enum.EnumMeta>
Ibby answered 20/9, 2021 at 14:40 Comment(1)
Welcome to Stack Overflow! I do not see how this answers the question at the top of this page, but it should. Please edit according to How to Answer or delete the answer. Otherwise it risks being flagged as "not an answer" and being deleted.Koniology
F
0

There are already good answers here but in case of it might be useful for some people out there I wanted to stretch the question a little further and created a simple example to propose a humble solution to help caller function who does maybe little knowledge about Enum solve problem of sending arguments to functions that take only Enum as a parameter by proposing a converter just below the file that Enum was created.

from enum import Enum
from typing import Union


class Polygon(Enum):
    triangle: 3
    quadrilateral: 4
    pentagon: 5
    hexagon: 6
    heptagon: 7
    octagon: 8
    nonagon: 9
    decagon: 10



def display(polygon: Polygon):
    print(f"{polygon.name} : {polygon.value} ")


def do_something_with_polygon(polygon: Polygon):
    """This one is not flexible cause it only accepts a Polygon Enum it does not convert"""

    """ if parameter is really a Polygon Enum we are ready to do stuff or We get error """
    display(polygon)


def do_something_with_polygon_more_flexible(maybe_polygon_maybe_not: Union[Polygon, int, str]):
    """ it will be more convenient function by taking extra parameters and converting"""
    if isinstance(maybe_polygon_maybe_not, Enum):
        real_polygon = maybe_polygon_maybe_not
    else:
        real_polygon = get_enum_with_value(int(maybe_polygon_maybe_not), Polygon, Polygon.quadrilateral)

    """ now we are ready to do stuff """
    display(real_polygon)


def get_enum_with_value(key: int, enum_: any, default_value: Enum):
    """ this function will convert int value to Enum that corresponds checking parameter key """

    # create a dict with all values and name of Enum
    dict_temp = {x.value: x for x in
                 enum_}  # { 3 : Polygon.triangle , 4 :Polygon.quadrilateral , 5 : Polygon.pentagon , ...  }

    # if key exists for example 6 or '6' that comes to do_something_with_polygon_more_flexible
    # returns Polygon.hexagon
    enum_value = dict_temp.get(key, None)
    # if key does not exist we get None
    if not enum_value:
        ...  # if key does not exist we return default value (Polygon.quadrilateral)
        enum_value = default_value  # Polygon.quadrilateral

    return enum_value
Fitzwater answered 16/10, 2022 at 22:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.