输入通用(协议)类参数的注释
我正在尝试计算如何为应该是实现通用协议的类函数参数添加类型注释。
例如,假设我有一个可以看起来像这样的集合的协议:
from typing import (
Protocol, TypeVar, Iterable
)
T = TypeVar('T', contravariant=True)
class Set(Protocol[T]):
"""A set of elements of type T."""
def __init__(self, init: Iterable[T]) -> None:
"""Initialise set with init."""
...
def __contains__(self, x: T) -> bool:
"""Test if x is in set."""
...
def add(self, x: T) -> None:
"""Add x to the set."""
...
def remove(self, x: T) -> None:
"""Remove x from the set."""
...
并且我有一种使用各种类型集的算法,我想通过设置实现来参数。为简单起见,我将在此功能中创建一个列表以用作示例:
from typing import Type
def foo(set_type: Type[Set]) -> None:
"""Do clever stuff."""
x = list(range(10))
s = set_type(x)
...
mypy
告诉我set
缺少一个类型参数,我想是正确的,但我不想给它一个,因为我打算使用不同类型的set_type
。
如果我给出set
a typevar
而是
def foo(set_type: Type[Set[T]]) -> None:
"""Do clever stuff"""
x = list(range(10))
s = set_type(x)
...
得到我的警告:i set_type()
获得不兼容的类型,list> list [int]
而不是itoble [t]
,这又是正确的,但对我没有太大帮助。
有没有办法指定我的函数参数可以用作不同类型集的通用构造函数?
I'm trying to work out how to add a type annotation for a function argument that should be a class implementing a generic protocol.
As an example, assume I have a protocol for a set that could look something like this:
from typing import (
Protocol, TypeVar, Iterable
)
T = TypeVar('T', contravariant=True)
class Set(Protocol[T]):
"""A set of elements of type T."""
def __init__(self, init: Iterable[T]) -> None:
"""Initialise set with init."""
...
def __contains__(self, x: T) -> bool:
"""Test if x is in set."""
...
def add(self, x: T) -> None:
"""Add x to the set."""
...
def remove(self, x: T) -> None:
"""Remove x from the set."""
...
and I have an algorithm that uses sets of various types, that I want to parameterise with the set implementation. For simplicity I'll just create a list in this function to use as an example:
from typing import Type
def foo(set_type: Type[Set]) -> None:
"""Do clever stuff."""
x = list(range(10))
s = set_type(x)
...
Here, mypy
tells me that Set
is missing a type parameter, which I suppose is correct, but I don't want to give it one, as I plan to use set_type
with different types.
If I give Set
a TypeVar
instead
def foo(set_type: Type[Set[T]]) -> None:
"""Do clever stuff"""
x = list(range(10))
s = set_type(x)
...
I instead get the warning that I set_type()
gets an incompatible type, List[int]
instead of Iterable[T]
, which again is correct, but doesn't help me much.
Is there a way to specify that my function argument can be used as a generic constructor for sets of different types?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
协议
什么也没说__ Init __
的签名,即使它是在协议
上定义的。type
做类似的事情 - 即使set
不是协议
,type [set]
什么也没说如何调用类型。我最初建议使用
callable [[iTable [t]],set [t]]
。但是,这是有问题的,并且仅是因为我省略了通用参数,从本质上讲,它使其成为>任何,如这个github问题。您可以使用(而不是冗长)协议。Protocol
says nothing about the signature of__init__
, even if it's defined on theProtocol
.Type
does a similar thing - even ifSet
isn't aProtocol
,Type[Set]
says nothing about how the type is called.I initially suggested using
Callable[[Iterable[T]], Set[T]]
. However, this is problematic, and only works because I omitted the generic parameter, essentially making itAny
, as discussed in this Github issue. You can instead use a (rather verbose) protocol.