Python Enum类(使用tostring fromstring)

Nic*_*ick 8 python enums tostring

我找到了一种简单的方法来实现(破解)枚举到Python:

class MyEnum:
  VAL1, VAL2, VAL3 = range(3)
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼它:

bob = MyEnum.VAL1
Run Code Online (Sandbox Code Playgroud)

性感!

好吧,现在我希望能够在给定字符串时获得数值,或者如果给定数值则获得字符串.假设我希望字符串与Enum键完全匹配

我能想到的最好的是这样的:

class MyEnum:
  VAL1, VAL2, VAL3 = range(3)
  @classmethod
  def tostring(cls, val):
    if (val == cls.VAL1):
      return "VAL1"
    elif (val == cls.VAL2):
      return "VAL2"
    elif (val == cls.VAL3):
      return "VAL3"
    else:
      return None
  @classmethod
  def fromstring(cls, str):
    if (str.upper() == "VAL1"):
      return cls.VAL1
    elif (str.upper() == "VAL2"):
      return cls.VAL2
    elif (str.upper() == "VAL2"):
      return cls.VAL2
    else:
      return None
Run Code Online (Sandbox Code Playgroud)

或类似的东西(忽略我如何捕捉无效案件)

有没有更好的,更蟒蛇为中心的方式去做我上面做的事情?或者以上内容已经尽可能简洁.

似乎必须有一个更好的方法来做到这一点.

Eth*_*man 19

[时间流逝...]

新的Python Enum终于登陆了3.4,并且也被推迟了.所以你的问题的答案现在就是使用它.:)


一个例子:

>>> from enum import Enum
>>> class Modes(Enum) :
...    Mode1 = "M1"
...    Mode2 = "M2"
...    Mode3 = "M3"
...

>>> Modes.Mode1
<Modes.Mode1: 'M1'>

>>> Modes.Mode1.value
'M1'

>>> Modes.Mode1.value
'M1'

>>> Modes['Mode1']    # index/key notation for name lookup
<Modes.Mode1: 'M1'>

>>> Modes('M1')       # call notation for value lookup
<Modes.Mode1: 'M1'>

>>> Modes("XXX")      # example error
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda3\lib\enum.py", line 291, in __call__
    return cls.__new__(cls, value)
  File "C:\Anaconda3\lib\enum.py", line 533, in __new__
    return cls._missing_(value)
  File "C:\Anaconda3\lib\enum.py", line 546, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 'XXX' is not a valid Modes
Run Code Online (Sandbox Code Playgroud)


Joc*_*zel 10

那么,这就是你要求的:

class MyEnum:
  VAL1, VAL2, VAL3 = range(3)
  @classmethod
  def tostring(cls, val):
    for k,v in vars(cls).iteritems():
        if v==val:
            return k

  @classmethod
  def fromstring(cls, str):
      return getattr(cls, str.upper(), None)

print MyEnum.fromstring('Val1')
print MyEnum.tostring(2)
Run Code Online (Sandbox Code Playgroud)

但我真的不明白Python中的Enums.它拥有如此丰富的类型系统以及管理状态的生成器和协同程序.

我知道我已经超过12年没有在Python中使用Enums了,也许你也可以摆脱它们;-)

  • 如果枚举在Python中没有任何用处,那么多年来有多少人觉得有必要实现像他们这样的东西,这很奇怪.我个人使用它的一种方法是为魔术数字之类的东西命名,并使我的脚本更具描述性和可读性. (5认同)
  • 不仅有多少人觉得有必要实施它们,这不仅奇怪; 他们不知何故最终进入了标准库!显然,对他们来说有很大的用处. (4认同)
  • "tostring"和"fromsring"肯定是javesque.Python不需要这种琐事. (2认同)

Raf*_*ler 7

使用词典:

MyEnum = {'VAL1': 1, 'VAL2':2, 'VAL3':3}
Run Code Online (Sandbox Code Playgroud)

没有必要的课程.Dicts让你的班级节拍,因为1.)他们非常有效率,2.)有一堆令人难以置信的方法,而且3.)是一种通用的语言结构.它们也是可扩展的:

MyEnum['VAL4'] = 4
Run Code Online (Sandbox Code Playgroud)

在Python中实现C++(或其他语言)功能并不明智.如果你发现自己"乱搞枚举"或那种性质的东西,你可以打赌你不是用Python方式做的那个农场.

如果你想采取相反的方式,建立另一个字典.(例如{'1':'VAL1', ...}

  • 如果我必须以另一种方式构建第二个字典,那就违反了任何语言中首选的单点定义值.你如何回应这种担忧? (2认同)