2017-08-24 68 views
3

我在Python的輸入系統和__slots__之間發生衝突。這是一個小的可重現的例子。__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

我會說這是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__一次:

>>> MyClass.__slots__ 
['my_member'] 
>>> MyClass.__dict__ 
mappingproxy({..., 'my_member': <member 'my_member' of 'MyClass' objects>, ...}) 

當我們這樣做type('MySubClass', (MyClass,), dict(MyClass.__dict__)),我們傳遞my_member兩次,一旦通過MyClass.__dict__,類型機械正在抱怨它。

除了避免使用__slots__或致電register()而不是繼承子類之外,您可以做的並不多。

+0

我認爲這是一個錯誤,但想確定。我已經提交了一份報告。 –