我从这个代码片段开始,根据我的理解,它本质上是一个类工厂来模拟其他语言的“枚举”类型:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
(我从这里拿来的:How can I represent an 'Enum' in Python?)
我知道它是如何工作的,而且确实如此,但我想让我的动态生成的类(“枚举”类型)可迭代,以便我可以执行以下操作以进行完整性检查:
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
但是,为了使完整性检查起作用,我需要使 MyEnum 可迭代。我在这里阅读:http://pydanny.blogspot.com/2007/10/required-methods-to-make-class-iterable.html我需要向某些东西添加 iter len contains 和 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
那么,如何使生成的 Enum 类可迭代,以便我可以对它们使用“in”一词?这对我来说不是生死攸关的事,但我正在通过这样做学习大量的 Python。
最佳答案
使用比 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')
不过,您可能希望使用实际属性来存储枚举键,而不是依赖于类字典。
关于Python:使动态创建的类(如在类本身中)可迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6970718/