2013-10-12 2 views
5

Python 3.4 имеет новый модуль enum и тип данных Enum. Если вы еще не можете переключиться на 3.4, Enum has been backported.Как положить docstrings на Enums?

Поскольку члены Enum поддерживают docstrings, так как почти все объекты python, я бы хотел их установить. Есть ли простой способ сделать это?

ответ

3

Да, есть, и это мой любимый рецепт. В качестве бонуса также не нужно указывать целочисленное значение. Вот пример:

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" 

Вы можете спросить, почему я не просто "N S E W NE NW SE SW" быть значение ordinal? Потому что, когда я получаю его репрезентацию, видя, что <AddressSegment.ordinal: 'N S E W NE NW SE SW'> получает немного неуклюжий, но наличие этой информации, легко доступной в docstring, является хорошим компромиссом.

Вот рецепт для Enum:

class AutoEnum(enum.Enum): 
    """ 
    Automatically numbers enum members starting from 1. 

    Includes support for a custom docstring per member. 

    """ 
    __last_number__ = 0 

    def __new__(cls, *args): 
     """Ignores arguments (will be handled in __init__.""" 
     value = cls.__last_number__ + 1 
     cls.__last_number__ = value 
     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,)) 

Поэтому я обработать аргументы в __init__, а не в __new__, чтобы сделать подклассов AutoEnum легче должен я хочу продлить его дальше.