__slots__与泛型类中的类变量冲突

时间:2017-08-24 14:29:29

标签: python python-3.x python-3.5 typing slots

我在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__

,同一个类也可以正常工作

1 个答案:

答案 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()而不是子类化之外,你无能为力。