cls*_*udt 11 python python-3.x
我需要在Python中模拟枚举,并通过编写类来完成它:
class Spam(Enum):
k = 3
EGGS = 0
HAM = 1
BAKEDBEANS = 2
Run Code Online (Sandbox Code Playgroud)
现在,我想测试某个常量是否是特定Enum派生类的有效选择,使用以下语法:
if (x in Foo):
print("seems legit")
Run Code Online (Sandbox Code Playgroud)
因此,我尝试创建一个"Enum"基类,我在其中覆盖这样的__contains__方法:
class Enum:
"""
Simulates an enum.
"""
k = 0 # overwrite in subclass with number of constants
@classmethod
def __contains__(cls, x):
"""
Test for valid enum constant x:
x in Enum
"""
return (x in range(cls.k))
Run Code Online (Sandbox Code Playgroud)
但是,在in类上使用关键字时(如上例所示),我收到错误:
TypeError: argument of type 'type' is not iterable
Run Code Online (Sandbox Code Playgroud)
为什么?我可以以某种方式获得我想要的语法糖吗?
Dev*_*rre 18
为什么?
当您使用特殊语法时a in Foo,会查询该__contains__方法的类型Foo.但是,您的__contains__实现Foo本身存在,而不是其类型.Foo的类型是type,它没有实现这个(或迭代),因此错误.
如果实例化一个对象,然后在创建对象后,__contains__向实例变量添加一个函数,则会出现相同的情况.该函数不会被调用:
>>> class Empty: pass
...
>>> x = Empty()
>>> x.__contains__ = lambda: True
>>> 1 in x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'Empty' is not iterable
Run Code Online (Sandbox Code Playgroud)
我可以以某种方式获得我想要的语法糖吗?
是.如上所述,该方法是在Foo类型上查找的.类的类型称为元类,因此您需要一个实现的新元类__contains__.
试试这个:
class MetaEnum(type):
def __contains__(cls, x):
return x in range(cls.k)
Run Code Online (Sandbox Code Playgroud)
如您所见,元类上的方法将元类实例(类)作为它们的第一个参数.这应该是有道理的.它与类方法非常相似,只不过该方法存在于元类而不是类.
从具有自定义元类的类继承也会继承元类,因此您可以创建一个基类,如下所示:
class BaseEnum(metaclass=MetaEnum):
pass
class MyEnum(BaseEnum):
k = 3
print(1 in MyEnum) # True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2693 次 |
| 最近记录: |