在 python 中枚举 class
Enum class in python
我想在 python 中创建枚举 class。我还需要一些 get_str() 方法,例如:
class Operation (object):
START = 0
STOP = 1
(...)
def get_str(self):
operation_dispatcher = {
Operation.START: "start",
Operation.STOP: "stop",
(...)
}
return operation_dispatcher[self]
但不幸的是,这种方法行不通。对象是整数,我收到错误消息 'int' 对象没有属性 'get_str'...你知道如何实现该功能吗?
我尝试做类似的事情:
Operation.get_str(operation_reference) 以及 operation_reference.get_str()
更新:
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]()
我建议使用元classes 来实现您的目标,以最大限度地减少客户端代码。所以首先检查下面的 metaclass:
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
它只是使用属性值作为构造函数参数来覆盖 __getattribute__
和 return 子 class 的实例。它还会更新原始值,以免每次都创建一个新实例,此外还使用对象的引用进行相等性检查
然后像这样定义一个Enum
class:
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)
这个基础 class 实现等于 (==
) 运算符,使用 int 值和 __repr__
方法与 return 枚举的字符串表示形式进行比较.所以给你:
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"
Enum
s in Python 是:
- 自 Python 3.4
起内置
- 可作为 backport 用于 Python 3.3 至 Python 2.4
- 在 enhanced library 中可用,其中还包括基于 class 的
NamedTuple
和 Constant
class
使用它你的代码看起来像:
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
我想在 python 中创建枚举 class。我还需要一些 get_str() 方法,例如:
class Operation (object):
START = 0
STOP = 1
(...)
def get_str(self):
operation_dispatcher = {
Operation.START: "start",
Operation.STOP: "stop",
(...)
}
return operation_dispatcher[self]
但不幸的是,这种方法行不通。对象是整数,我收到错误消息 'int' 对象没有属性 'get_str'...你知道如何实现该功能吗?
我尝试做类似的事情:
Operation.get_str(operation_reference) 以及 operation_reference.get_str()
更新:
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]()
我建议使用元classes 来实现您的目标,以最大限度地减少客户端代码。所以首先检查下面的 metaclass:
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
它只是使用属性值作为构造函数参数来覆盖 __getattribute__
和 return 子 class 的实例。它还会更新原始值,以免每次都创建一个新实例,此外还使用对象的引用进行相等性检查
然后像这样定义一个Enum
class:
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)
这个基础 class 实现等于 (==
) 运算符,使用 int 值和 __repr__
方法与 return 枚举的字符串表示形式进行比较.所以给你:
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"
Enum
s in Python 是:
- 自 Python 3.4 起内置
- 可作为 backport 用于 Python 3.3 至 Python 2.4
- 在 enhanced library 中可用,其中还包括基于 class 的
NamedTuple
和Constant
class
使用它你的代码看起来像:
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