Enum class in python
本问题已经有最佳答案,请猛点这里访问。
我想在python中创建一个枚举类。我还需要一些get_str()方法,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Operation (object): START = 0 STOP = 1 (...) def get_str(self): operation_dispatcher = { Operation.START:"start", Operation.STOP:"stop", (...) } return operation_dispatcher[self] |
但不幸的是,这种方法不起作用。对象是ints,我收到错误消息"int"对象没有属性"get_str"…你知道如何实现这个功能吗?
我试着做如下的事情:
operation.get_str(operation_reference)和operation_reference.get_str()。
更新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | class EnumMeta(type): def __getattribute__(self, name): return self(super(EnumMeta, self).__getattribute__(name)) class Enum(object): __metaclass__ = EnumMeta def __init__(self, value): super(Enum, self).__init__() self.value = value[0] self.repr = value[1] def __eq__(self, other): if isinstance(other, Enum): return self.value == other.value elif isinstance(other, int): return self.value == other else: return object.__eq__(Enum, other) def __repr__(self): return str(self.repr) class Operation(Enum): START = (0,"start") STOP = (1,"stop") (...) operation_dispatcher = { Operation.START: start_method, Operation.STOP: stop_method, (...) } # invoking operation_dispatcher[Operation.START.value]() |
python中的
- 从python 3.4开始内置
- 可作为从python3.3到python2.4的后端端口使用
- 可在增强型库中使用,该库还包括基于类的
NamedTuple 和Constant 类。
使用它,您的代码看起来像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from aenum import IntEnum # or from enum import IntEnum class Operation(IntEnum): START = 0 STOP = 1 >>> Operation.START <Operation.START: 0> >>> Operation['START'] <Operation.START: 0> >>> Operation(0) <Operation.START: 0> >>> Operation.STOP is Operation.STOP True >>> list(Operation) [<Operation.START: 0>, <Operation.STOP: 1>] >>> Operation.STOP.name 'STOP' >>> Operation.STOP.value 1 |
我建议您使用元类来实现目标,以最小化客户机代码。所以首先检查下面的元类:
1 2 3 4 5 6 7 8 9 | class EnumMeta(type): def __getattribute__(self, name): actual_value = super(EnumMeta, self).__getattribute__(name) if isinstance(actual_value, self): return actual_value else: new_value = self(actual_value) super(EnumMeta, self).__setattr__(name, new_value) return new_value |
它只重写
然后这样定义一个
1 2 3 4 5 6 7 8 9 10 11 | class Enum(object): __metaclass__ = EnumMeta def __init__(self, value): super(Enum, self).__init__() self.value = value[0] self.repr = value[1] def __repr__(self): return str(self.repr) |
该基类实现equals(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Operation(Enum): START = (0,"start") STOP = (1,"stop") >>> Operation.START == Operation.START True >>> Operation.START is Operation.START True >>> Operation.START == Operation.STOP False >>> Operation.START "start" >>> repr(Operation.STOP) "stop" |