【问题标题】:Convert enum to int in python在python中将枚举转换为int
【发布时间】:2011-08-28 23:20:46
【问题描述】:

我有一个枚举国籍:

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

但我没有,而且这种方式对于 python 来说太大了。我敢肯定还有更简单的东西。

【问题讨论】:

  • 类不是枚举。因此你无法比较。

标签: python enums


【解决方案1】:

请使用IntEnum

from enum import IntEnum

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

int(loggertype.Info)
0

【讨论】:

  • 请解释你的答案。
  • 从 Python 3.4 开始,这是“更正确”的答案(或者,创建库的人,下面是 Ethan Furman 的答案)。
  • 在上面的例子中你也可以导入auto,然后将Warning、Error、Fatal初始化为auto()。
【解决方案2】:

使用enum34 backportaenum1 你可以创建一个专门的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'

上面使用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

具有以下附加功能:

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

1 披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum) 库的作者。

【讨论】:

  • 效果很好。非常感谢!
【解决方案3】:

有更好(和更“Pythonic”)的方式来做你想做的事。

使用元组(或列表,如果需要修改),其中的顺序将被保留:

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

或者使用字典:

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

在我看来,后者更可取,因为它更具可读性和明确性。

namedtuple 在您的特定情况下也可能有用,尽管它可能有点矫枉过正:

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

【讨论】:

  • 您错过了国籍名称。我必须拥有它们
  • @user278618 - 为了简洁起见,我将它们排除在外。这个想法是你会在Nationality 类的某个地方使用某种查找表。你可以很容易地替换你的类属性,而不是字符串。
【解决方案4】:

为什么不将值定义为数字而不是字符串:

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

如果您需要访问两个字母的名称,您可以简单地提供一个映射它们的表。 (或以其他方式映射的字典等)

【讨论】:

    【解决方案5】:
    from enum import Enum
    
    class Phone(Enum):
        APPLE = 1 #do not write comma (,)
        ANDROID = 2
    
    #as int:
    Phone.APPLE.value
    

    如果使用逗号,则需要按索引访问元组:

    class Phone(Enum):
        APPLE = 1, # note: there is comma (,)
        ANDROID = 2,
    
    #as int:
    Phone.APPLE.value[0]
       
    

    【讨论】:

      【解决方案6】:

      你不能。 Python 不存储类元素的顺序,dir() 会以任意顺序返回它们。

      从您的评论中看到,您确实需要从字符串到整数的映射,实际上您应该这样做:

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

      【讨论】:

      • 我正在使用这个枚举来设置 select 的值,该值在几个具有不同 css 和语言的站点上,并且每个站点上只有 value 属性相同。从这个选择中我必须选择国籍,选项的值为0,1,2。我在 c# 中使用了这个转换,所以这是我的想法。
      【解决方案7】:

      我见过类似的东西:

      PL, FR, DE = range(3)
      

      将它包装在一个类中,viola,你就有了一个枚举的命名空间。

      【讨论】:

        【解决方案8】:
        from enum import Enum
        
        class Nationality(Enum):
            Poland = 'PL'
            Germany = 'DE'
            France = 'FR'
        
            @classmethod
            def get_index(cls, type):
                return list(cls).index(type)
        

        然后:

        Nationality.get_index(Nationality.Poland)
        0
        

        【讨论】:

          【解决方案9】:

          实现此目的的一种简单方法:

          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)
          

          输出:

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

          说明:您可以根据需要创建具有所需数字和字符串表示的枚举,并通过覆盖各自的 __int____str__ 方法获得所需的功能。据我所知,这不会违反enum 的任何约定,我更愿意将功能封装在各自的类中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-01-23
            • 2011-08-18
            • 2010-09-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多