1

I'm trying to override iteration behavior for a Flag enum:

from enum import Flag, auto

class MyFlags(Flag):
    A = auto()
    B = auto()
    C = auto()
    
    D = A | C

    def __iter__(self):
       for x in super().__iter__():
           if x.value % 2 == 0:
                yield x

But it seems the __iter__ is never actually called:

>>> list(MyFlags)
[MyFlags.A, MyFlags.B, MyFlags.C, MyFlags.D]

How can I override iteration behavior here?

martineau
  • 119,623
  • 25
  • 170
  • 301
bwk
  • 622
  • 6
  • 18
  • 3
    `__iter__(self)` is for an instance object, you're calling it on the class itself – azro Oct 28 '20 at 18:26

1 Answers1

1

You can sublass EnumMeta and then add metaclass= to your Enum class:

from enum import Flag, EnumMeta, auto


class MyEnumMeta(EnumMeta):
    def __iter__(self):
       for x in super().__iter__():
           if x.value % 2 == 0:
                yield x


class MyFlags(Flag, metaclass=MyEnumMeta):
    A = auto()
    B = auto()
    C = auto()
    
    D = A | C


print(list(MyFlags))

Prints:

[<MyFlags.B: 2>, <MyFlags.C: 4>]
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91