泛型协议:mypy错误:参数1的类型不兼容;预期

8ftvxx2r  于 2021-09-08  发布在  Java
关注(0)|答案(0)|浏览(203)

我正在尝试实现一个通用协议。我的目的是使用一个带有简单getter的widget[key\u type,value\u type]协议。mypy抱怨 Protocol[K, T] 这样就变成了 Protocol[K_co, T_co] . 我已经去掉了所有其他的限制,但我甚至不能得到最基本的情况, widg0: Widget[Any, Any] = ActualWidget() ,工作。actualwidget.get应与完全兼容 get(self, key: K) -> Any ,这让我觉得我在某种程度上使用泛型/协议是错误的,或者mypy无法处理这个问题。
来自mypy的命令/错误:

$ mypy cat_example.py
cat_example.py:34: error: Argument 1 to "takes_widget" has incompatible type "ActualWidget"; expected "Widget[Any, Any]"
cat_example.py:34: note: Following member(s) of "ActualWidget" have conflicts:
cat_example.py:34: note:     Expected:
cat_example.py:34: note:         def [K] get(self, key: K) -> Any
cat_example.py:34: note:     Got:
cat_example.py:34: note:         def get(self, key: str) -> Cat
Found 1 error in 1 file (checked 1 source file)

或者,如果我试图用 widg0: Widget[Any, Any] = ActualWidget() :

error: Incompatible types in assignment (expression has type "ActualWidget", variable has type "Widget[Any, Any]")

完整代码:

from typing import Any, TypeVar
from typing_extensions import Protocol, runtime_checkable

K = TypeVar("K")  # ID/Key Type
T = TypeVar("T")  # General type
K_co = TypeVar("K_co", covariant=True)  # ID/Key Type or subclass
T_co = TypeVar("T_co", covariant=True)  # General type or subclass
K_contra = TypeVar("K_contra", contravariant=True)  # ID/Key Type or supertype
T_contra = TypeVar("T_contra", contravariant=True)  # General type or supertype

class Animal(object): ...

class Cat(Animal): ...

@runtime_checkable
class Widget(Protocol[K_co, T_co]):
    def get(self, key: K) -> T_co: ...

class ActualWidget(object):
    def get(self, key: str) -> Cat:
        return Cat()

def takes_widget(widg: Widget):
    return widg

if __name__ == '__main__':
    widg0 = ActualWidget()
    #widg0: Widget[str, Cat] = ActualWidget()
    #widg0: Widget[Any, Any] = ActualWidget()

    print(isinstance(widg0, Widget))
    print(isinstance({}, Widget))
    takes_widget(widg0)

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题