【问题标题】:__slots__ conflicts with a class variable in a generic class__slots__ 与泛型类中的类变量冲突
【发布时间】:2018-02-02 11:50:00
【问题描述】:

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

,相同的类也可以正常工作

【问题讨论】:

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


    【解决方案1】:

    我会说这是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() 而不是子类化之外,您无能为力。

    【讨论】:

    • 我认为这是一个错误,但想确定一下。我已经提交了一份报告。
    • @EliKorvigo 这个错误修复了吗?
    • 是的,他们已经修复了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    相关资源
    最近更新 更多