初始化python标志实用工具类的最佳方法?

时间:2019-03-21 17:13:14

标签: python-3.x enums flags enum-flags

我正在研究Python3.7中的实用程序类,该类使使用标志更加用户友好(至少对我而言)

基本上,我想把它转过来

from enum import Flag as eFlag, auto, unique

@unique
class Flag(eFlag):
    A = auto()
    B = auto()

flags = Flag.A
flags |= Flag.B
if flags & Flag.B:
    pass

对此:

flags = Flags()
flags.set(Flag.A, Flag.B)
if flags.is_set(Flag.A):
    pass

为此,我有一个Flags类,如下所示:

class Flags:

    def set(self, *flags):
        self.raw |= self.merge(*flags)

    def clear(self, *flags):
        self.raw &= ~self.merge(*flags)

    def is_set(self, *flags):
        return bool(self.raw & self.merge(*flags))

    @classmethod
    def merge(cls, *flags):
        F = None
        for f in flags:
            F |= f
        return F

    def __str__(self):
        return str(self.raw)

问题是 init 方法中的 raw 属性的初始化。我知道可以将其设置为0,但是 Flag 的基数必须为 enum.IntFlag ,并且我想将其保留为 enum。根据{{​​3}}标记。合并方法中存在相同的问题,因为我有 F = None ,然后尝试将其与标志进行“或”运算。

如果可以肯定Flag枚举具有 NONE = 0 属性,则可以在Flags类中执行以下操作:

def __init__(self, FlagCls):
    self.raw = FlagCls.NONE

但是我无法强制执行,可能要与其他人的代码一起使用。


  1. 有没有Python的方法可以做到这一点?
  2. 作为模块功能会更好:flags = set(flags,Flag.A)吗?
  3. 是否有更好的方法来执行合并方法而不从functools导入reduce?
  4. 或者最好不要使用* flags并强制使用显式的 flags.set(Flag.A | Flag.B)而不是 flags.set(Flag.A,Flag)。 B)吗?

1 个答案:

答案 0 :(得分:1)

即使0不是Flag,也可以将其设置为IntFlag,因为这表示未设置标志的状态:

>>> @unique
... class Flag(eFlag):
...     A = auto()
...     B = auto()
... 

>>> Flag.A & Flag.B
<Flag.0: 0>

>>> Flag(0)
<Flag.0: 0>