初始化 python 标志实用程序 class 的最佳方法?
Best way to initialize a python flag utility class?
我正在 Python3.7 中开发实用程序 class,这使得使用标志更加用户友好(至少对我而言)
基本上我想转这个
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
为此,我有一个像这样的标志 class:
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)
问题是 raw 属性在 init 方法中的初始化。我知道我可以将它设置为 0,但是 Flag 的基数必须是 enum.IntFlag,我想按照docs保持为enum.Flag。合并方法中存在同样的问题,因为我有 F = None,然后尝试用标志对其进行 OR。
如果保证 Flag 枚举具有 NONE = 0 属性,我可以在 Flags class:
def __init__(self, FlagCls):
self.raw = FlagCls.NONE
但我不能强制执行,可能想将其与其他人的代码一起使用。
- 有没有 Pythonic 的方法来做到这一点?
- 作为模块函数会不会更好:flags = set(flags, Flag.A) ?
- 没有从functools 导入reduce 的情况下,是否有更好的方法来执行merge 方法?
- 或者最好不要使用 * 标志并强制使用显式 flags.set(Flag.A | Flag.B) 而不是 flags.set(Flag.A, Flag.B) ?
即使 Flag
不是 IntFlag
,您也可以将其设置为 0
,因为这表示未设置标志的状态:
>>> @unique
... class Flag(eFlag):
... A = auto()
... B = auto()
...
>>> Flag.A & Flag.B
<Flag.0: 0>
>>> Flag(0)
<Flag.0: 0>
我正在 Python3.7 中开发实用程序 class,这使得使用标志更加用户友好(至少对我而言)
基本上我想转这个
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
为此,我有一个像这样的标志 class:
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)
问题是 raw 属性在 init 方法中的初始化。我知道我可以将它设置为 0,但是 Flag 的基数必须是 enum.IntFlag,我想按照docs保持为enum.Flag。合并方法中存在同样的问题,因为我有 F = None,然后尝试用标志对其进行 OR。
如果保证 Flag 枚举具有 NONE = 0 属性,我可以在 Flags class:
def __init__(self, FlagCls):
self.raw = FlagCls.NONE
但我不能强制执行,可能想将其与其他人的代码一起使用。
- 有没有 Pythonic 的方法来做到这一点?
- 作为模块函数会不会更好:flags = set(flags, Flag.A) ?
- 没有从functools 导入reduce 的情况下,是否有更好的方法来执行merge 方法?
- 或者最好不要使用 * 标志并强制使用显式 flags.set(Flag.A | Flag.B) 而不是 flags.set(Flag.A, Flag.B) ?
即使 Flag
不是 IntFlag
,您也可以将其设置为 0
,因为这表示未设置标志的状态:
>>> @unique
... class Flag(eFlag):
... A = auto()
... B = auto()
...
>>> Flag.A & Flag.B
<Flag.0: 0>
>>> Flag(0)
<Flag.0: 0>