表示Flag枚举中的所有值

安全

我想在我的python Flags枚举中有一个“ ALL”标志,

myenum.EVERY_MEMBER & myenum.ALL == myenum.EVERY_MEMBER

成立。我目前有:

from enum import Flag, auto

class RefreshFlags(Flag):
    NONE = 0
    EVENTS = auto()
    RESOURCES = auto()
    BUILDINGS = auto()
    DEFENSES = auto()
    .....

因为这个枚举可能在任何发展状态下都会增长,所以我想

@property
def ALL(self):
    retval = self.NONE
    for member in self.__members__.values():
        retval |= member
    return retval

这不起作用:

RefreshFlags.EVENTS  & RefreshFlags.ALL

TypeError: unsupported operand type(s) for &: 'RefreshFlags' and 'property'

请注意,这个问题目前仅与python 3.6或更高版本有关。

伊森·弗曼(Ethan Furman)

有几种方法可以解决此问题:


使用类属性方法要注意的一件事是,因为描述符是在类而不是元类上定义的,所以缺少针对设置和删除的常规保护措施-换句话说:

>>> RefreshFlags.ALL
<RefreshFlags.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15>

>>> RefreshFlags.ALL = 'oops'
>>> RefreshFlags.ALL
'oops'

创建一个新的基类:

# lightly tested
from enum import Flag, auto
from operator import or_ as _or_
from functools import reduce

class AllFlag(Flag):

    @classproperty
    def ALL(cls):
        cls_name = cls.__name__
        if not len(cls):
            raise AttributeError('empty %s does not have an ALL value' % cls_name)
        value = cls(reduce(_or_, cls))
        cls._member_map_['ALL'] = value
        return value

并在使用中:

class RefreshFlag(AllFlag):
    EVENTS = auto()
    RESOURCES = auto()
    BUILDINGS = auto()
    DEFENSES = auto()

>>> RefreshFlag.ALL
<RefreshFlag.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15>

ALL属性中有趣的区别是名称的设置_member_map_-这允许为Enum成员提供相同的保护:

>>> RefreshFlag.ALL = 9
Traceback (most recent call last):
  ....
AttributeError: Cannot reassign members.

但是,这里有一个竞争条件:如果在第一次激活之前RefreshFlag.ALL = ...发生 RefreshFlag.ALL那么它将被破坏;因此,在这种情况下,我将使用装饰器,因为装饰器将在处理Enum之前对其进行处理。

# lightly tested

from enum import Flag, auto
from operator import or_ as _or_
from functools import reduce

def with_limits(enumeration):
    "add NONE and ALL psuedo-members to enumeration"
    none_mbr = enumeration(0)
    all_mbr = enumeration(reduce(_or_, enumeration))
    enumeration._member_map_['NONE'] = none_mbr
    enumeration._member_map_['ALL'] = all_mbr
    return enumeration

并在使用中:

@with_limits
class RefreshFlag(Flag):
    EVENTS = auto()
    RESOURCES = auto()
    BUILDINGS = auto()
    DEFENSES = auto()

>>> RefreshFlag.ALL = 99
Traceback (most recent call last):
  ...
AttributeError: Cannot reassign members.

>>> RefreshFlag.ALL 
<RefreshFlag.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15>

>>> RefreshFlag.NONE
<RefreshFlag.0: 0>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在 Swift 中传递所有枚举值

在 Swift 中传递所有枚举值

枚举C中的所有枚举名称/值

是否有任何方法可以获取在FlagsAttributed枚举中不是类型的所有Flag?

如何从[Flag]枚举属性中检索值?

替换列表中的所有值而不使用枚举?

如何获取Java中的所有枚举值?

在Scala中获取所有枚举用例对象的值

如何遍历C#中的所有枚举值?

用Java中的所有枚举值填充列表

如何在java中打印所有枚举值?

使用LINQ选择枚举中的所有标记值

我应该测试合同中的所有枚举值吗?

如何在Java中获取枚举的所有可能值?(不知道具体的枚举)

NestJS - Swagger - 显示所有枚举值

获取所有值代表标志枚举中的十进制值

如何在C中枚举枚举中的所有内容?

如何在Java中显示数据库中的所有枚举值

枚举GraphQL查询中的所有字段

枚举序列中的所有选项

如何处理空参数JPA查询方法中的所有枚举值

如何使用Spring和Thymeleaf在下拉列表中显示所有可能的枚举值?

如何通过Hibernate获取mysql中枚举类型的所有可能值

如何获取字符串枚举中的所有值?

确保枚举类型的所有值都包含在函数体中

如何强制 Set 对象包含枚举中的所有值 - TS

如何将枚举中所有常量的值提取到char数组中?

使用TryParse将字符串值与C#中的枚举中的所有值进行比较-逻辑问题

有没有办法强制执行,你切换所有定义Java中的枚举值?