Конвертировать enum в int в python - PullRequest
11 голосов
/ 19 мая 2011

У меня есть enum Национальность:

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

Как я могу преобразовать это перечисление в int таким или иным способом:

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

Я знаю, что могу сделать это, если бы у меня был код:

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

но у меня нет, и этот путь выглядит слишком большим для питона. Я уверен, что есть что-то гораздо более простое.

Ответы [ 6 ]

18 голосов
/ 03 апреля 2018

пожалуйста, используйте IntEnum

from enum import IntEnum

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

int(loggertype.Info)
0
13 голосов
/ 13 марта 2016

Использование либо enum34 backport , либо aenum 1 Вы можете создать специализированный 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

и используется:

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

Выше написано легче, используя aenum 1 :

# 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

, который имеет дополнительную функциональность:

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

1 Раскрытие информации: я являюсь автором Python stdlib Enum, enum34 backport и Advanced Enumeration ( aenum) библиотека.

11 голосов
/ 19 мая 2011

Существуют лучшие (и более "питонские") способы делать то, что вы хотите.

Либо используйте кортеж (или список, если это необходимо изменить), где порядок будет сохранен:

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

Или используйте словарь в следующих строках:

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

Последний вариант, на мой взгляд, предпочтительнее, так как он более читабелен и явен.

A namedtuple также может быть полезно, в вашем конкретном случае, хотя это, вероятно, излишне:

import collections
Nationalities = collections.namedtuple('Nationalities', 
                                       ['Poland', 'France', 'Germany'])
nat = Nationalities('PL', 'FR', 'DE')
print nat.Poland
print nat.index(nat.Germany)
5 голосов
/ 19 мая 2011

Вы не можете. Python не хранит порядок элементов класса, и dir() будет возвращать их в любом порядке.

Видя из вашего комментария, что вам действительно требуется сопоставление строк и целых чисел, вы должны сделать именно это:

code_lookup = {
    'PL': ("Poland", 0), 
    'DE': ("Germany", 1), 
    'FR': ("France", 2), 
    ... 
}
4 голосов
/ 19 мая 2011

Я видел что-то вроде:

PL, FR, DE = range(3)

Оберните его в класс и альт , у вас есть пространство имен для перечисления.

4 голосов
/ 19 мая 2011

Почему бы вам просто не определить значения как числа вместо строк:

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

Если вам нужен доступ к двухбуквенным именам, вы можете просто предоставить таблицу, которая отображает их.(Или словарь, который отображает другой путь и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...