python enumeration_python枚举防止无效的属性分配

要使枚举类完全“只读”,只需要使用

__setattr__

hook

防止

全部的

属性分配。因为元类附加到类

之后

它是创建的,分配正确的枚举值没有问题。

就像伊桑的回答一样,我用的是

EnumMeta

类作为自定义元类的基础:

from enum import EnumMeta, Enum

class FrozenEnumMeta(EnumMeta):

"Enum metaclass that freezes an enum entirely"

def __new__(mcls, name, bases, classdict):

classdict['__frozenenummeta_creating_class__'] = True

enum = super().__new__(mcls, name, bases, classdict)

del enum.__frozenenummeta_creating_class__

return enum

def __call__(cls, value, names=None, *, module=None, **kwargs):

if names is None: # simple value lookup

return cls.__new__(cls, value)

enum = Enum._create_(value, names, module=module, **kwargs)

enum.__class__ = type(cls)

return enum

def __setattr__(cls, name, value):

members = cls.__dict__.get('_member_map_', {})

if hasattr(cls, '__frozenenummeta_creating_class__') or name in members:

return super().__setattr__(name, value)

if hasattr(cls, name):

msg = "{!r} object attribute {!r} is read-only"

else:

msg = "{!r} object has no attribute {!r}"

raise AttributeError(msg.format(cls.__name__, name))

def __delattr__(cls, name):

members = cls.__dict__.get('_member_map_', {})

if hasattr(cls, '__frozenenummeta_creating_class__') or name in members:

return super().__delattr__(name)

if hasattr(cls, name):

msg = "{!r} object attribute {!r} is read-only"

else:

msg = "{!r} object has no attribute {!r}"

raise AttributeError(msg.format(cls.__name__, name))

class FrozenEnum(Enum, metaclass=FrozenEnumMeta):

pass

上面区分了已经可用的属性和新的属性,以便于诊断。它还阻止属性

删除

,这可能同样重要!

它还提供元类和

FrozenEnum

基类

用于枚举;使用它而不是

Enum

.

冻结样品

Color

枚举:

>>> class Color(FrozenEnum):

... red = 1

... green = 2

... blue = 3

...

>>> list(Color)

[, , ]

>>> Color.foo = 'bar'

Traceback (most recent call last):

# ...

AttributeError: 'Color' object has no attribute 'foo'

>>> Color.red = 42

Traceback (most recent call last):

# ...

Cannot reassign members.

>>> del Color.red

Traceback (most recent call last):

# ...

AttributeError: Color: cannot delete Enum member.

注意

全部的

不允许更改属性,不允许使用新属性,也阻止删除。当名称是枚举成员时,我们委托给原始成员

枚举元

处理以保持错误消息稳定。

如果枚举使用更改枚举类属性的属性,则必须将这些属性白名单,或者允许设置以单个下划线开头的名称;在

第二组

确定允许设置和使用的名称

super().__setattr__(name, value)

对于这些异常,就像代码现在通过使用标志属性区分类构造和以后的更改一样。

上面的类可以像

Enum()

要以编程方式创建枚举,请执行以下操作:

e = FrozenEnum('Things', [('foo',1), ('bar',2)]))

演示:

>>> e = FrozenEnum('Things', [('foo',1), ('bar',2)])

>>> e

>>> e.foo = 'bar'

Traceback (most recent call last):

# ...

AttributeError: Cannot reassign members.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值