python enumeration_python枚举防止无效的属性分配
要使枚舉類完全“只讀”,只需要使用
__setattr__
hook
防止
全部的
屬性分配。因?yàn)樵惛郊拥筋?/p>
之后
它是創(chuàng)建的,分配正確的枚舉值沒有問題。
就像伊桑的回答一樣,我用的是
EnumMeta
類作為自定義元類的基礎(chǔ):
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
上面區(qū)分了已經(jīng)可用的屬性和新的屬性,以便于診斷。它還阻止屬性
刪除
,這可能同樣重要!
它還提供元類和
FrozenEnum
基類
用于枚舉;使用它而不是
Enum
.
凍結(jié)樣品
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.
注意
全部的
不允許更改屬性,不允許使用新屬性,也阻止刪除。當(dāng)名稱是枚舉成員時(shí),我們委托給原始成員
枚舉元
處理以保持錯(cuò)誤消息穩(wěn)定。
如果枚舉使用更改枚舉類屬性的屬性,則必須將這些屬性白名單,或者允許設(shè)置以單個(gè)下劃線開頭的名稱;在
第二組
確定允許設(shè)置和使用的名稱
super().__setattr__(name, value)
對于這些異常,就像代碼現(xiàn)在通過使用標(biāo)志屬性區(qū)分類構(gòu)造和以后的更改一樣。
上面的類可以像
Enum()
要以編程方式創(chuàng)建枚舉,請執(zhí)行以下操作:
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.
總結(jié)
以上是生活随笔為你收集整理的python enumeration_python枚举防止无效的属性分配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图片句柄_PC微信逆向:自动保存加密的聊
- 下一篇: javascript中实例对象和构造函数