Лучший способ инициализировать служебный класс флага Python? - PullRequest
1 голос
/ 21 марта 2019

Я работаю над утилитарным классом в 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

Но я не могу применить это на практике и, возможно, захочу использовать это с чужим кодом.


  1. Есть ли Pythonic способ сделать это?
  2. Было бы лучше в качестве функций модуля: flags = set (flags, Flag.A)?
  3. Есть ли лучший способ сделать метод слияния, не импортируя метод less из functools?
  4. Или лучше не использовать * flags и принудительно устанавливать flags.set (Flag.A | Flag.B) вместо flags.set (Flag.A, Flag.B ) ?

1 Ответ

1 голос
/ 21 марта 2019

Вы можете установить его на 0, даже если Flag не будет IntFlag, так как оно представляет состояние отсутствия установленного флага:

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

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

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