在python中的枚举转换器

时间:2011-02-24 12:42:15

标签: python enums

我有一个枚举

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 个答案:

答案 0 :(得分:5)

最好的解决方案是从一开始就创建字典。你的枚举在Python中没有意义,它只是不必要的复杂。看起来你正在尝试编写Java code,这与Python代码看起来完全相反。

答案 1 :(得分:3)

Python 3.4有一个新的Enum数据类型(which has been backported),可以轻松支持您的用例:

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

从名称中获取枚举成员:

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

从值中获取枚举成员:

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

一旦你有枚举成员:

--> member = Nationality('FR')
--> member.name
'France'
--> member.value
'FR'

答案 2 :(得分:2)

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

答案 3 :(得分:2)

您想改用dict吗?

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

print Nationality["DE"] # prints 'Germany'

答案 4 :(得分:1)

我的方法就像这个(可能不完美,但你明白了):

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

希望这有帮助。

答案 5 :(得分:0)

转换为枚举的纯方法怎么样?只需将它存放在util lib中即可。或者你可以将它放在一个基本的枚举类上,并将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()