Eli*_*igo 5 python typing slots python-3.x python-3.5
我在 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]
Run Code Online (Sandbox Code Playgroud)
现在每当我尝试指定内容类型时,例如
V = TestGeneric[int]
Run Code Online (Sandbox Code Playgroud)
我得到
ValueError: 'test' in __slots__ conflicts with class variable
Run Code Online (Sandbox Code Playgroud)
我Generics 在没有插槽的类中使用了很多,因此我认为这个错误必须与__slots__. 此外,同一个类工作正常,如果你删除__slots__
我会说这是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
Run Code Online (Sandbox Code Playgroud)
对type()上面的类型调用相当于typing模块中幕后发生的事情。
此异常是由以下事实引起的:当您使用 时__slots__,您指定的成员会自动添加到类型 dict 中:
>>> MyClass.__slots__
['my_member']
>>> MyClass.__dict__
mappingproxy({..., 'my_member': <member 'my_member' of 'MyClass' objects>, ...})
Run Code Online (Sandbox Code Playgroud)
当我们这样做时type('MySubClass', (MyClass,), dict(MyClass.__dict__)),我们通过了my_member两次:一次通过MyClass.__slots__,一次通过MyClass.__dict__,类型机器抱怨它。
除了避免使用__slots__或调用register()而不是子类化之外,您无能为力。
| 归档时间: |
|
| 查看次数: |
3567 次 |
| 最近记录: |