Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中定义通用协变函数?_Python_Python 3.x_Function_Generics_Python Typing - Fatal编程技术网

如何在Python中定义通用协变函数?

如何在Python中定义通用协变函数?,python,python-3.x,function,generics,python-typing,Python,Python 3.x,Function,Generics,Python Typing,我想定义一个函数example,它接受类型为Widget的参数,或者任何扩展Widget并返回与参数相同类型的参数。因此,如果按钮扩展了小部件,调用示例(Button())将返回类型按钮 我尝试了以下方法: T_co=TypeVar('T_co',小部件,协变=True) def示例(小部件:T_co)->T_co: ... 但是,类型检查器(Pyright)忽略协方差。在进一步研究后,我发现以下内容: 注意:协方差或逆方差不是类型变量的属性,而是使用此变量定义的泛型类的属性。差异仅适用于泛型

我想定义一个函数
example
,它接受类型为
Widget
的参数,或者任何扩展
Widget
并返回与参数相同类型的参数。因此,如果
按钮
扩展了
小部件
,调用
示例(Button())
将返回类型
按钮

我尝试了以下方法:

T_co=TypeVar('T_co',小部件,协变=True)
def示例(小部件:T_co)->T_co:
...
但是,类型检查器(Pyright)忽略协方差。在进一步研究后,我发现以下内容:

注意:协方差或逆方差不是类型变量的属性,而是使用此变量定义的泛型类的属性。差异仅适用于泛型类型;泛型函数没有此属性。后者应仅使用不带
协变
逆变
关键字参数的类型变量来定义

但是,如果我尝试定义一个泛型函数,而不使用注释中指定的协变参数:

T\u co=TypeVar('T\u co',小部件)
def示例(小部件:T_co)->T_co:
...
我只能将
小部件
类型的值传递给函数(而不是
按钮


我怎样才能做到这一点呢?

我能在表格中找到答案。原来我是在寻找
绑定的
,而不是
协变的
。可以这样做:

T = TypeVar('T', bound=Widget)

def example(widget: T) -> T:
  ...

对不起,有点迷路了。
type(myVar)
是否不能准确返回所需内容?如果是这样的话,您可以只使用isinstance(mVar,Widget),因为isinstance可以处理继承。@错误语法自责我在寻找编译器(Pyright)类型检查,而不是运行时静态类型检查,而不是编译时(因为python并不是真正编译)。在这种情况下,我建议切换到MyPy,它更常用,因此有更多的功能使您的生活更轻松。也就是说,如果您正在制作一个供其他人使用的包,那么您最好使用类型暗示,而不是尝试强制执行,并且在运行时处理类型。谢谢,static是正确的术语。我知道MyPy,但Pyright正确处理了这个特殊问题;在PEP 484中是这样的。我只是对解决方法感兴趣。