【问题标题】:Python3 - Convert enum to different datatypesPython3 - 将枚举转换为不同的数据类型
【发布时间】:2018-03-25 22:47:49
【问题描述】:

我目前正在使用以下类型的枚举:

class System(Enum):
  FIRST = 1
  SECOND = 2

现在我希望能够做到以下几点:

a = System.FIRST
url = a.getSystemURL()

枚举成员FIRSTSECOND的url当然是不同的。

我可以创建一个字典,其中枚举成员作为键,url 作为值,但这并不能保证如果我以后添加一个枚举成员,我会记得添加相应的字典条目。

是否有一种简洁的方法可以为枚举成员提供具有多个值的枚举?并命名这些不同的值?

类似这样的:

class System(Enum):
  Values = (Value, url, something)
  FIRST = 1, 'https://www.example.com', 42
  SECOND = 2, 'https://www.test.com', 13

【问题讨论】:

    标签: python python-3.x enums type-conversion enumeration


    【解决方案1】:

    文档中有这样的an example。如果该类定义了__init__ 方法,则枚举值将作为参数传递给它。这意味着您可以像这样定义您的枚举:

    class System(Enum):
        FIRST = 1, 'https://www.example.com', 42
        SECOND = 2, 'https://www.test.com', 13
    
        def __init__(self, value, url, something):
            self.value_ = value
            self.url = url
            self.something = something
    

    (注意value是枚举保留的特殊属性,所以我将属性命名为value_以避免名称冲突。)

    您现在可以访问每个枚举成员的这些属性:

    >>> System.FIRST.url
    'https://www.example.com'
    

    【讨论】:

    • 谢谢。这正是我想要的!如果我只使用一个属性。我还应该将ints 添加到定义中吗?对于枚举,您是否更愿意只放置 url 以便 enum_mem.valueenum_mem.url 会给出相同的结果?
    • @user9115052 我会说这取决于您的用例。一般来说,没有必要为每个枚举值关联一个整数。但是,如果您在程序中使用该整数,请继续添加它。
    【解决方案2】:

    stdlib Enumaenum1 都可以轻松支持您的用例(尽管 stdlib 版本需要做更多工作)。


    stdlib enum 3.4+(有关__new____init__ 的说明,请参阅文档。)

    import enum
    class System(enum.Enum):
    
        def __new__(cls, *args, **kwds):
            value = len(cls.__members__) + 1
            obj = object.__new__(cls)
            obj._value_ = value
            return obj
    
        def __init__(self, url, something):
            self.url = url
            self.something = something
    
        FIRST = 'https://www.example.com', 42
        SECOND = 'https://www.test.com', 13
    

    aenum -- 可用于 Python 2 和 3 代码。 aenum 也让一些事情变得更容易——上面的代码是:

    import aenum
    class System(aenum.AutoNumberEnum):
        _init_ = 'url something'
        FIRST = 'https://www.example.com', 42
        SECOND = 'https://www.test.com', 13
    

    并在使用中:

    --> System.FIRST
    <System.First: 1>
    
    --> System.FIRST.url
    'https://www.example.com'
    

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

    【讨论】:

      【解决方案3】:

      将值设为namedtuple

      from collections import namedtuple
      from enum import Enum
      
      Entry = namedtuple('Entry', ['value', 'url', 'something'])
      
      class System(Enum):
        FIRST = Entry(1, 'https://www.example.com', 42)
        SECOND = Entry(2, 'https://www.test.com', 13)
      
      print(System.FIRST.value.url)
      # https://www.example.com
      

      【讨论】:

        【解决方案4】:

        您是否尝试过您编写的代码?它已经可以工作了!当然,你真的没有多个值,你只有一个元组值——但这不是问题:

        >>> class System(Enum):
        ...     FIRST = 1, 'https://www.example.com', 42
        ...     SECOND = 2, 'https://www.test.com', 13
        >>> _, url, _ = System.SECOND.value
        >>> url
        'https://www.example.com'
        >>> a = System.FIRST
        >>> url = a.value[1]
        >>> url
        'https://www.example.com'
        

        你可以做一些事情来让它变得更好,比如使用namedtuple而不是普通的tuple,这样你就可以写a.value.url而不是a.value[1],但是你已经写了一些东西有效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-11
          • 2023-02-21
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多