Python3.4有一个新的枚举模块和枚举数据类型.如果你还不能切换到3.4,Enum has been backported.
由于Enum成员支持docstring,就像几乎所有python对象一样,我想设置它们.有没有简单的方法?
Python3.4有一个新的枚举模块和枚举数据类型.如果你还不能切换到3.4,Enum has been backported.
由于Enum成员支持docstring,就像几乎所有python对象一样,我想设置它们.有没有简单的方法?
是的,这是我到目前为止最喜欢的食谱.作为奖励,也不必指定整数值.下面是一个例子:
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
?因为当我得到它的repr SEING <AddressSegment.ordinal: 'N S E W NE NW SE SW'>
时,会有点笨拙,但在文档字符串中随时可以获得这些信息是一个很好的折衷方案.
以下是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,))
在使用中:
>>> list(AddressSegment)
[<AddressSegment.ordinal: 1>, <AddressSegment.secondary: 2>, <AddressSegment.misc: 3>, <AddressSegment.street: 4>]
>>> AddressSegment.secondary
<AddressSegment.secondary: 2>
>>> AddressSegment.secondary.__doc__
'apt bldg floor etc'
我在__init__
而不是__new__
中处理参数的原因是,如果我想进一步扩展它,那么子类AutoEnum
就更容易了.