Python3 - 将枚举转换为不同的数据类型

Python3 - Convert enum to different datatypes

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

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

现在我希望能够执行以下操作:

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

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

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

有没有一种简洁的方法可以让枚举成员具有多个值的枚举?并命名这些不同的值?

像这样:

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

使值成为 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

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

>>> 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], 但你已经写了一些有用的东西。

文档中有an example这样的。如果 class 定义了一个 __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'

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


stdlib enum 3.4+(有关 __new__ and __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 Enum, the enum34 backport, and the Advanced Enumeration (aenum) 库的作者。