Я работаю над утилитарным классом в 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)
Проблема заключается в инициализации атрибута raw в методе init . Я знаю, что могу установить его на 0, но тогда для Flag база должна быть enum.IntFlag , и я хотел бы оставить его как enum.Flag в соответствии с документами . Та же проблема существует в методе слияния, так как у меня есть F = Нет , а затем попробуйте ИЛИ с флагом.
Если бы перечисление Flag гарантированно имело атрибут NONE = 0 , я мог бы сделать что-то подобное в классе Flags:
def __init__(self, FlagCls):
self.raw = FlagCls.NONE
Но я не могу применить это на практике и, возможно, захочу использовать это с чужим кодом.
- Есть ли Pythonic способ сделать это?
- Было бы лучше в качестве функций модуля: flags = set (flags, Flag.A)?
- Есть ли лучший способ сделать метод слияния, не импортируя метод less из functools?
- Или лучше не использовать * flags и принудительно устанавливать flags.set (Flag.A | Flag.B) вместо flags.set (Flag.A, Flag.B ) ?