可以在 Enum 中添加自定义错误以显示有效值吗?

Cle*_*leb 4 python enums

假设我有

from enum import Enum

class SomeType(Enum):
    TYPEA = 'type_a'
    TYPEB = 'type_b'
    TYPEC = 'type_c'
Run Code Online (Sandbox Code Playgroud)

如果我现在这样做

SomeType('type_a')
Run Code Online (Sandbox Code Playgroud)

我会得到

<SomeType.TYPEA: 'type_a'>
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。当我做

SomeType('type_o')
Run Code Online (Sandbox Code Playgroud)

我会收到

ValueError:“type_o”不是有效的 SomeType

这也是预料之中的。

我的问题是:可以以某种方式轻松自定义错误,以便它显示所有有效类型吗?所以,就我而言,我希望

ValueError:“type_o”不是有效的 SomeType。有效类型为“type_a”、“type_b”、“type_c”。

Eth*_*man 8

使用_missing_方法:

from enum import Enum

class SomeType(Enum):
    TYPEA = 'type_a'
    TYPEB = 'type_b'
    TYPEC = 'type_c'
    @classmethod
    def _missing_(cls, value):
        raise ValueError(
                '%r is not a valid %s.  Valid types: %s' % (
                    value,
                    cls.__name__,
                    ', '.join([repr(m.value) for m in cls]),
                    ))
Run Code Online (Sandbox Code Playgroud)

并在使用中:

>>> SomeType('type_a')
<SomeType.TYPEA: 'type_a'>

>>> SomeType('type_o')
ValueError: 'type_o' is not a valid SomeType

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
ValueError: 'type_o' is not a valid SomeType.  Valid types: 'type_a', 'type_b', 'type_c'
Run Code Online (Sandbox Code Playgroud)

如您所见,异常链接有点笨重,因为 Enum 本身会引发“primary” ValueError,而您丢失的错误位于链中。根据您的需求,您可以缩小ValueError您所提出的范围_missing_,仅包含有效类型:

from enum import Enum

class SomeType(Enum):
    TYPEA = 'type_a'
    TYPEB = 'type_b'
    TYPEC = 'type_c'
    @classmethod
    def _missing_(cls, value):
        raise ValueError(
                'Valid types: %s' % (
                    ', '.join([repr(m.value) for m in cls]),
                    )
Run Code Online (Sandbox Code Playgroud)

并在使用中:

>>> SomeType('type_o')
ValueError: 'type_o' is not a valid SomeType

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
ValueError: Valid types: 'type_a', 'type_b', 'type_c'
Run Code Online (Sandbox Code Playgroud)

声明:我是Python stdlibEnumenum34backportAdvanced Enumeration ( aenum)库的作者 。