How do I put docstrings on Enums?

前端 未结 2 1213
春和景丽
春和景丽 2020-12-09 16:58

Python 3.4 has a new enum module and Enum data type. If you are unable to switch to 3.4 yet, Enum has been backported.

Since Enum members support docstrings, as pre

2条回答
  •  一向
    一向 (楼主)
    2020-12-09 17:41

    Yes there is, and it's my favorite recipe so far. As a bonus, one does not have to specify the integer value either. Here's an example:

    class AddressSegment(AutoEnum):
        misc = "not currently tracked"
        ordinal = "N S E W NE NW SE SW"
        secondary = "apt bldg floor etc"
        street = "st ave blvd etc"
    

    You might ask why I don't just have "N S E W NE NW SE SW" be the value of ordinal? Because when I get its repr seeing gets a bit clunky, but having that information readily available in the docstring is a good compromise.

    Here's the recipe for the Enum:

    class AutoEnum(enum.Enum):
        """
        Automatically numbers enum members starting from 1.
    
        Includes support for a custom docstring per member.
        """
        #
        def __new__(cls, *args):
            """Ignores arguments (will be handled in __init__."""
            value = len(cls) + 1
            obj = object.__new__(cls)
            obj._value_ = value
            return obj
        #
        def __init__(self, *args):
            """Can handle 0 or 1 argument; more requires a custom __init__.
    
            0  = auto-number w/o docstring
            1  = auto-number w/ docstring
            2+ = needs custom __init__
    
            """
            if len(args) == 1 and isinstance(args[0], (str, unicode)):
                self.__doc__ = args[0]
            elif args:
                raise TypeError('%s not dealt with -- need custom __init__' % (args,))
    

    And in use:

    >>> list(AddressSegment)
    [, , , ]
    
    >>> AddressSegment.secondary
    
    
    >>> AddressSegment.secondary.__doc__
    'apt bldg floor etc'
    

    The reason I handle the arguments in __init__ instead of in __new__ is to make subclassing AutoEnum easier should I want to extend it further.

提交回复
热议问题