Enum конвертер в Python - PullRequest
       4

Enum конвертер в Python

5 голосов
/ 24 февраля 2011

У меня есть перечисление

class Nationality:
        Poland='PL'
        Germany='DE'
        France='FR'
        ...
        Spain='ES'

У меня есть 2 прототипа методов:

# I want somethink like in c#        
def convert_country_code_to_country_name(country_code):
        print Enum.Parse(typeof(Nationality),country_code)

#this a second solution ,but it has a lot of ifs

def convert_country_code_to_country_name(country_code):
        if country_code=='DE':
                print Nationality.Germany #btw how to print here 'Germany', instead 'DE'

Вот как я хочу вызвать этот метод:

convert_country_code_to_country_name('DE') # I want here to  print 'Germany'

Как реализовать это в python?

Ответы [ 6 ]

5 голосов
/ 24 февраля 2011

Лучшим решением было бы создать словарь с самого начала. Ваше перечисление не имеет смысла в Python, оно просто излишне сложно. Похоже, вы пытаетесь написать Java-код , что совершенно противоположно тому, как должен выглядеть код Python.

3 голосов
/ 10 октября 2013

Python 3.4 имеет новый тип данных Enum (, который был перенесен ), который легко поддерживает ваш случай использования:

class Nationality(enum.Enum):
    Poland = 'PL'
    Germany = 'DE'
    France = 'FR'
    Spain = 'ES'

Чтобы получить член enum из имени:

--> Nationality['France']
<Nationality.France: 'FR'>

Чтобы получить член перечисления из значения:

--> Nationalatiy('FR')
<Nationality.France: 'FR'>

И как только вы получите член перечисления:

--> member = Nationality('FR')
--> member.name
'France'
--> member.value
'FR'
2 голосов
/ 24 февраля 2011

Хотите вместо этого использовать dict?

Nationality = { 
    "PL" : "Poland",
    "DE": "Germany"}

print Nationality["DE"] # prints 'Germany'
2 голосов
/ 24 февраля 2011
class Nationality:
        Poland='PL'
        Germany='DE'
        France='FR'
        Spain='ES'

nationalityDict = {}
for k, v in Nationality.__dict__.iteritems():
    if not k.startswith('__'):
        nationalityDict[v] = k

А теперь: nationalityDict['DE'] содержит Germany.

1 голос
/ 24 февраля 2011

Мой подход был бы таким (возможно, не идеальным, но вы поняли):

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

        def convertToCodeFromName(name):
                return getattr(Nationality, name)

        def convertToNameFromCode(code):
                lookFor = None

                for member in dir(Nationality):
                        if (getattr(Nationality, member) == code):
                                lookFor = member
                                break
                return lookFor

print(Nationality.convertToCodeFromName("Poland"))
print(Nationality.convertToNameFromCode("PL"))

Надеюсь, это поможет.

0 голосов
/ 19 марта 2015

Как насчет чистого метода для преобразования в enum?Просто спрятать это в утилите lib.Или вы можете поместить его в базовый класс Enum и установить для target_enum значение по умолчанию self.

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

from enum import Enum
def to_enum(v,target_enum,default = None):
    '''
    if v is given enum, return it
    if v is an int, convert to enum via int convert
    if v is str convert to enum via string convert
    '''
    ret = default

    if v is None:
        return ret

    if v in target_enum:
        return v

    try:
        return target_enum(int(v))
    except Exception:
        pass

    try:
        return target_enum[str(v)]
    except Exception:
        pass

    return ret

Вот класс unittest для него.

import unittest
from enum import Enum,unique
class EnumTest(Enum):
    T0 = 0
    T1 = 1

class EnumTest2(Enum):
    T0 = 0
    T1 = 1

class EnumUtilTest(unittest.TestCase):
    def test_to_enum(self):
        '''str, int, and Enum should be convertable '''
        r = Util.to_enum(1,EnumTest)
        self.assertEqual(r,EnumTest.T1)
        r = Util.to_enum('T1',EnumTest)
        self.assertEqual(r,EnumTest.T1)
        r = Util.to_enum(EnumTest.T1,EnumTest)
        self.assertEqual(r,EnumTest.T1)
        r = Util.to_enum('1',EnumTest)
        self.assertEqual(r,EnumTest.T1)

    def test_to_enum_fail(self): 
        '''Return None if convert fails'''       
        self.assertIsNone(Util.to_enum( None,EnumTest ))
        self.assertIsNone(Util.to_enum( 'abd',EnumTest ))
        self.assertIsNone(Util.to_enum( 123,EnumTest ))
        self.assertIsNone(Util.to_enum( EnumTest2.T1,EnumTest ))

    def test_to_enum_default(self):
        '''test default param'''
        r = Util.to_enum(EnumTest2.T1,EnumTest,EnumTest.T0)
        self.assertEqual(r,EnumTest.T0)

if __name__ == '__main__':
    unittest.main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...