Prabhakar Shanmugam
Prabhakar Shanmugam

Reputation: 6144

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

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.

Upvotes: 44

Views: 60089

Answers (5)

Sermet Pekin
Sermet Pekin

Reputation: 355

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

Upvotes: 0

user8234870
user8234870

Reputation:

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

Upvotes: 2

lsfzem
lsfzem

Reputation: 11

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

print(o.__class__.__class__) 

Output:

<enum.EnumMeta>

Upvotes: 0

iperov
iperov

Reputation: 514

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

Upvotes: 0

Ethan Furman
Ethan Furman

Reputation: 69051

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):

Upvotes: 83

Related Questions