如何将文档附加到python枚举的成员?

Eri*_*ric 6 python enums

我想以一种IPython可以找到的方式为python枚举的每个成员提供文档。我现在所拥有的是:

class Color(Enum):
    """
    RED: The color red
    GREEN: The color green
    BLUE: The color blue. These docstrings are more useful in the real example
    """
    RED = 1
    GREEN = 2
    BLUE = 3
Run Code Online (Sandbox Code Playgroud)

这不是很好,因为它重复了成员名称,并且使得仅要求一个成员的文档变得更加困难。

我可以得到我想要的东西

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
Color.RED.__doc__ = "The color red"
Color.GREEN.__doc__ = "The color green"
Color.BLUE.__doc__ = "The color blue. These docstrings are more useful in the real example"
Run Code Online (Sandbox Code Playgroud)

但这仍然遭受名称重复的困扰。

有更简单的方法吗?

Eri*_*ric 5

您可以重写Enum.__new__以接受doc如下参数:

class DocEnum(Enum):
    def __new__(cls, value, doc=None):
        self = object.__new__(cls)  # calling super().__new__(value) here would fail
        self._value_ = value
        if doc is not None:
            self.__doc__ = doc
        return self
Run Code Online (Sandbox Code Playgroud)

可以用作:

class Color(DocEnum):
    """ Some colors """
    RED   = 1, "The color red"
    GREEN = 2, "The color green"
    BLUE  = 3, "The color blue. These docstrings are more useful in the real example"
Run Code Online (Sandbox Code Playgroud)

在IPython中,它给出了以下内容:

In [17]: Color.RED?
Type:            Color
String form:     Color.RED
Docstring:       The color red
Class docstring: Some colors
Run Code Online (Sandbox Code Playgroud)

也可以使它适用于IntEnum

class DocIntEnum(IntEnum):
    def __new__(cls, value, doc=None):
        self = int.__new__(cls, value)  # calling super().__new__(value) here would fail
        self._value_ = value
        if doc is not None:
            self.__doc__ = doc
        return self
Run Code Online (Sandbox Code Playgroud)

  • 看起来 `Enum` 真的很奇怪,因为 `Enum.__new__` 根本不支持用于枚举实例的初始构造;一旦类已经建立,它*只*处理检索已经构造的实例。在枚举类初始化期间,`Enum.__new__` 被显式绕过以创建实例。 (2认同)

Eth*_*man 5

@Eric 已经展示了如何使用 stdlib做到这一点Enum;这是使用1 的方法aenum

from aenum import Enum  # or IntEnum


class Color(Enum):                     # or IntEnum

    _init_ = 'value __doc__'

    RED = 1, 'The color red'
    GREEN = 2, 'The color green'
    BLUE = 3, 'The color blue'
Run Code Online (Sandbox Code Playgroud)

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