【问题标题】:Is there a better way to get a named series of constants (enumeration) in Python? [duplicate]有没有更好的方法在 Python 中获取命名的一系列常量(枚举)? [复制]
【发布时间】:2010-09-16 20:21:15
【问题描述】:

只是看看在 python 中获取命名常量的方法。

class constant_list:
    (A_CONSTANT, B_CONSTANT, C_CONSTANT) = range(3)

那当然可以这样引用:

constant_list.A_CONSTANT

我想你可以使用字典,使用字符串:

constant_dic = {
    "A_CONSTANT" : 1,
    "B_CONSTANT" : 2,
    "C_CONSTANT" : 3,}

并像这样引用它:

constant_dic["A_CONSTANT"]

那么,我的问题很简单。有没有更好的方法来做到这一点?不是说这些是不够的或什么,只是好奇 - 我错过了任何其他常见的成语吗?

提前致谢。

【问题讨论】:

标签: python


【解决方案1】:

对于 2.3 或更高版本:

class Enumerate(object):
  def __init__(self, names):
    for number, name in enumerate(names.split()):
      setattr(self, name, number)

使用方法:

 codes = Enumerate('FOO BAR BAZ')

codes.BAZ 将是 2,依此类推。

如果您只有 2.2,请在此之前加上:

 from __future__ import generators

 def enumerate(iterable):
   number = 0
   for name in iterable:
     yield number, name
     number += 1

这取自here

【讨论】:

  • 从对象继承似乎没有必要。但它有效,而且看起来很优雅。
  • 你从对象继承来创建一个新样式的类。
  • 如果你想给出有效字符串的枚举键并将值与之关联 Animal = Enum('Animal', {'ant1.0':1, 'bee':2})跨度>
【解决方案2】:

我发现枚举类配方(Active State,Python Cookbook)非常有效。

另外它还有一个很好的查找功能。

佩夫

【讨论】:

    【解决方案3】:

    constant_dic 的另一种构造:

    constants = ["A_CONSTANT", "B_CONSTANT", "C_CONSTANT"]
    constant_dic = dict([(c,i) for i, c in enumerate(constants)])
    

    【讨论】:

      【解决方案4】:

      下面的行为就像一个经典的“写在石头上”的 C 枚举——一旦定义,你就不能改变它,你只能读取它的值。你也不能实例化它。您所要做的就是“导入 enum.py”并从 Enum 类派生。

      # this is enum.py
      class EnumException( Exception ):
         pass
      
      class Enum( object ):
         class __metaclass__( type ):
            def __setattr__( cls, name, value ):
               raise EnumException("Can't set Enum class attribute!")
            def __delattr__( cls, name ):
               raise EnumException("Can't delete Enum class attribute!")
      
         def __init__( self ):
            raise EnumException("Enum cannot be instantiated!")
      

      这是测试代码:

      # this is testenum.py
      from enum import *
      
      class ExampleEnum( Enum ):
         A=1
         B=22
         C=333
      
      if __name__ == '__main__' :
      
         print "ExampleEnum.A |%s|" % ExampleEnum.A
         print "ExampleEnum.B |%s|" % ExampleEnum.B
         print "ExampleEnum.C |%s|" % ExampleEnum.C
         z = ExampleEnum.A
         if z == ExampleEnum.A:
            print "z is A"
      
         try:
             ExampleEnum.A = 4   
             print "ExampleEnum.A |%s| FAIL!" % ExampleEnum.A
         except EnumException:
             print "Can't change Enum.A (pass...)"
      
         try:
             del ExampleEnum.A
         except EnumException:
             print "Can't delete Enum.A (pass...)"
      
         try:
             bad = ExampleEnum()
         except EnumException:
             print "Can't instantiate Enum (pass...)"
      

      【讨论】:

        【解决方案5】:

        这是我见过的最好的:“Python 中的第一类枚举”

        http://code.activestate.com/recipes/413486/

        它给你一个类,这个类包含所有的枚举。枚举可以相互比较,但没有任何特定的价值;您不能将它们用作整数值。 (我一开始反对这个,因为我习惯了 C 枚举,它是整数值。但是如果你不能将它用作整数,你就不能将它用作整数 错误 所以总的来说,我认为这是一个胜利。)每个枚举都是一个独特的对象。您可以打印枚举,可以迭代它们,可以测试枚举值是否“在”枚举中。它非常完整和流畅。

        【讨论】:

          【解决方案6】:

          在 Python 中,字符串是不可变的,因此它们更适合用于常量而不是数字。在我看来,最好的方法是创建一个将常量保存为字符串的对象:

          class Enumeration(object):
              def __init__(self, possibilities):
                  self.possibilities = set(possibilities.split())
          
              def all(self):
                  return sorted(self.possibilities)
          
              def __getattr__(self, name):
                  if name in self.possibilities:
                      return name
                  raise AttributeError("Invalid constant: %s" % name)
          

          你可以这样使用它:

          >>> enum = Enumeration("FOO BAR")
          >>> print enum.all()
          ['BAR', 'FOO']
          >>> print enum.FOO
          FOO
          >>> print enum.FOOBAR
          Traceback (most recent call last):
            File "enum.py", line 17, in <module>
              print enum.FOOBAR
            File "enum.py", line 11, in __getattr__
              raise AttributeError("Invalid constant: %s" % name)
          AttributeError: Invalid constant: FOOBAR
          

          【讨论】:

          • 非常好。但这并不是真正的枚举,不是吗? :p
          • 嗯...对 :-) 但是你为什么需要在 Python 中使用 eNUMERation 呢?
          • 好吧,数字也是不可变的。他们只是没有自我记录..
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-17
          • 1970-01-01
          • 2011-12-28
          • 2013-05-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多