Python:使动态创建的类(如类本身)可迭代?

Ben*_*rts 3 python

我从这个代码片段开始,根据我的理解,它实际上是一个类别工厂,可以模拟其他语言的"枚举"类型:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)
Run Code Online (Sandbox Code Playgroud)

(我从这里拿走:我如何在Python中表示'Enum'?)

我知道它是如何工作的,它确实如此,但是我想让我的动态生成的类,类型为'Enum',可迭代,以便我可以执行以下操作以进行完整性检查:

MyEnum = enum('FOO', 'BAR', 'JIMMY')
def func(my_enum_value):  # expects one of the MyEnum values
    if not my_enum_value in MyEnum:
        raise SomeSortOfException
Run Code Online (Sandbox Code Playgroud)

但是,为了使完整性检查工作,我需要使MyEnum可迭代.我读到这里:http://pydanny.blogspot.com/2007/10/required-methods-to-make-class-iterable.html,我需要添加ITER LEN 包含的GetItem方法来东西,以使其可迭代.我开始走这条路(改写枚举代码)但被卡住了:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    enums['_enums'] = enums.copy() # (so I'd have them in the Class in order to use for the methods I'll be implementing to make it iterable)
    Enum = type('Enum', (), enums)

    Enum.__iter__ = #Er, how do I do this? Guess I'll ask SO
    Enum.__len__ =  # etc. 
    # . . . 
    return Enum
Run Code Online (Sandbox Code Playgroud)

那么,我如何使我生成的Enum类可迭代,以便我可以使用'in'字样?这对我来说不是生死攸关的,但是我通过这种方式学习了大量的Python.

Ign*_*ams 5

使用比更聪明的元类type.

class EnumMC(type):
  def __contains__(self, val):
    return val in self.__dict__

def enum(*sequential, **named):
  enums = dict(zip(sequential, range(len(sequential))), **named)
  return EnumMC('Enum', (), enums)

MyEnum = enum('FOO', 'BAR', 'JIMMY')
def func(my_enum_value):  # expects one of the MyEnum values
    if not my_enum_value in MyEnum:
        raise ValueError()

func('FOO')
func('QUUX')
Run Code Online (Sandbox Code Playgroud)

您可能希望使用实际属性来存储枚举键,而不是依赖于类字典.