我在Python的打字系统和__slots__
之间发生了冲突。这是一个可重复的小例子。
from typing import TypeVar, Generic, Sequence
T = TypeVar("T")
class TestGeneric(Sequence, Generic[T]):
__slots__ = ("test",)
def __init__(self, test: T):
self.test = [test]
def __iter__(self):
return iter(self.test)
def __len__(self):
return len(self.test)
def __contains__(self, item):
return item in self.test
def __getitem__(self, _):
return self.test[0]
现在每当我尝试指定内容类型时,例如
V = TestGeneric[int]
我得到了
ValueError: 'test' in __slots__ conflicts with class variable
我在没有插槽的类中使用Generics
,因此我认为此错误必须与__slots__
相关联。此外,如果删除__slots__
答案 0 :(得分:2)
我想说这是typing
模块中的一个错误,在创建新类型时没有正确考虑__slots__
。
这个问题可以通过这个非常简短的例子重现:
>>> class MyClass:
... __slots__ = ('my_member',)
...
>>> type('MySubClass', (MyClass,), dict(MyClass.__dict__))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 'my_member' in __slots__ conflicts with class variable
上面对type()
的类型调用相当于typing
模块中幕后发生的事情。
此异常是由于当您使用__slots__
时,您指定的成员会自动添加到类型dict中:
>>> MyClass.__slots__
['my_member']
>>> MyClass.__dict__
mappingproxy({..., 'my_member': <member 'my_member' of 'MyClass' objects>, ...})
当我们执行type('MySubClass', (MyClass,), dict(MyClass.__dict__))
时,我们将my_member
两次传递:一次通过MyClass.__slots__
,一次通过MyClass.__dict__
,类型机制正在抱怨它。
除了避免使用__slots__
或调用register()
而不是子类化之外,你无能为力。