Convert enum to int in python

Question:

I have an enum Nationality:

class Nationality:
        Poland='PL'
        Germany='DE'
        France='FR'

How can I convert this some enum to int in this or similar way:

position_of_enum = int(Nationality.Poland)  # here I want to get 0

I know that I can do it if I had code by:

counter=0
for member in dir(Nationality):
    if getattr(Nationality, member) == code:
        lookFor = member
        counter += 1
return counter

but I don’t have, and this way looks too big for python. I’m sure that there is something much simpler .

Asked By: user278618

||

Answers:

You can’t. Python does not store the order of class elements and dir() will return them in any order.

Seeing from your comment that you really do require a mapping from strings to integers, you should in fact do exactly that:

code_lookup = {
    'PL': ("Poland", 0), 
    'DE': ("Germany", 1), 
    'FR': ("France", 2), 
    ... 
}
Answered By: blubb

Why don’t you just define the values as numbers instead of strings:

class Nationality:
    POLAND = 0
    GERMANY = 1
    FRANCE = 2

If you need to access the two-letter names, you can simply provide a table that maps them. (Or a dictionary that maps the other way, etc.)

Answered By: andrewdski

There are better (and more “Pythonic”) ways of doing what you want.

Either use a tuple (or list if it needs to be modified), where the order will be preserved:

code_lookup = ('PL', 'DE', 'FR')
return code_lookup.index('PL') 

Or use a dictionary along the lines of:

code_lookup = {'PL':0, 'FR':2, 'DE':3}
return code_lookup['PL']  

The latter is preferable, in my opinion, as it’s more readable and explicit.

A namedtuple might also be useful, in your specific case, though it’s probably overkill:

import collections
Nationalities = collections.namedtuple('Nationalities', 
                                       ['Poland', 'France', 'Germany'])
nat = Nationalities('PL', 'FR', 'DE')
print nat.Poland
print nat.index(nat.Germany)
Answered By: Joe Kington

I have seen something like:

PL, FR, DE = range(3)

Wrap it in a class and viola, you have a namespace for the enumeration.

Answered By: janislaw

Using either the enum34 backport or aenum1
you can create a specialized Enum:

# using enum34
from enum import Enum

class Nationality(Enum):

    PL = 0, 'Poland'
    DE = 1, 'Germany'
    FR = 2, 'France'

    def __new__(cls, value, name):
        member = object.__new__(cls)
        member._value_ = value
        member.fullname = name
        return member

    def __int__(self):
        return self.value

and in use:

>>> print(Nationality.PL)
Nationality.PL
>>> print(int(Nationality.PL))
0
>>> print(Nationality.PL.fullname)
'Poland'

The above is more easily written using aenum1:

# using aenum
from aenum import Enum, MultiValue

class Nationality(Enum):
    _init_ = 'value fullname'
    _settings_ = MultiValue

    PL = 0, 'Poland'
    DE = 1, 'Germany'
    FR = 2, 'France'

    def __int__(self):
        return self.value

which has the added functionality of:

>>> Nationality('Poland')
<Nationality.PL: 0>

1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

Answered By: Ethan Furman

Please use IntEnum

from enum import IntEnum

class loggertype(IntEnum):
    Info = 0
    Warning = 1
    Error = 2
    Fatal = 3

int(loggertype.Info)
0
Answered By: ban
from enum import Enum

class Nationality(Enum):
    Poland = 'PL'
    Germany = 'DE'
    France = 'FR'

    @classmethod
    def get_index(cls, type):
        return list(cls).index(type)

and then:

Nationality.get_index(Nationality.Poland)
0
Answered By: Andrzej Piasecki
from enum import Enum

class Phone(Enum):
    APPLE = 1 #do not write comma (,)
    ANDROID = 2

#as int:
Phone.APPLE.value

Need to access tuple by index if using commas:

class Phone(Enum):
    APPLE = 1, # note: there is comma (,)
    ANDROID = 2,

#as int:
Phone.APPLE.value[0]
   
Answered By: Morris

One straightforward way to achieve this:

from enum import Enum

class Nationality(Enum):
    Poland= 1, 'PL'
    Germany= 2, 'DE'
    France= 3, 'FR'

    def __int__(self):
        return self.value[0]

    def __str__(self):
        return self.value[1]

# Example use
if __name__ == "__main__":
    print(int(Nationality.Poland))
    print(Nationality.Poland)
    print(int(Nationality.Poland) == 1)

Output:

>>> 1
>>> PL
>>> True

Explanation: You can create your enum with the desired numeration and string representation as you wish and you get the desired functionality by overwriting the respective __int__ and __str__ methods. To my knowledge, this does not break any contracts of enum and I prefer to keep functionality encapsulated in their respective classes.

Answered By: andbmme
class Nationality(Enum):
    Poland = 'PL'
    Germany = 'DE'
    France = 'FR'

    @property
    def ordinal(self):
        return list(self.__class__).index(self)

    @classmethod
    def get(cls, index):
        return list(cls)[index]

and then:

>>> Nationality.Poland.ordinal
0

also

>>> Nationality.get(2)
Nationality.France
Answered By: AboSari

This method is something I am using

from enum import Enum
ClientType_DICT = {
    "1": 'webapp',
    "2": 'application',
    "3": 'embedded'
}
ClientType_ENUM: Enum = Enum('ClientType_ENUM', ClientType_DICT)
print(int(ClientType_ENUM('webapp').name))

@app.post("/example")
def login(device_type: ClientType_ENUM):
    deviceType = int(device_type.name) # print 1
Answered By: Thinkal VB
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.