Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.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_Oop_Type Hinting_Static Typing_Pyright - Fatal编程技术网

我可以在Python中限制子类的类型吗?

我可以在Python中限制子类的类型吗?,python,oop,type-hinting,static-typing,pyright,Python,Oop,Type Hinting,Static Typing,Pyright,假设我想在集合和列表上定义包装器类,添加一些有用的方法,如下所示: from abc import ABC class AbstractGizmo(ABC): def bloviate(self): print(f"Let me tell you more about my {len(self)} elements") class ListGizmo(list, AbstractGizmo): pass class SetGiz

假设我想在集合和列表上定义包装器类,添加一些有用的方法,如下所示:

from abc import ABC

class AbstractGizmo(ABC):

    def bloviate(self):
        print(f"Let me tell you more about my {len(self)} elements")

class ListGizmo(list, AbstractGizmo):
    pass    

class SetGizmo(set, AbstractGizmo):
    pass
现在我可以打电话:

>>> ListGizmo([1, 2, 3]).bloviate()
>>> SetGizmo({1, 2, 3}).bloviate()
但我也希望将
bloviate()
作为一种实用方法单独提供:

from typing import Union, Set, List

def bloviate(collection: Union[Set, List]):
    print(f"Let me tell you more about my {len(collection)} elements")


class AbstractGizmo(ABC):

    def bloviate(self):
        return bloviate(self)
所以我也可以做:

>>> bloviate([1, 2, 3])
>>> bloviate({1, 2, 3})
由于子类
ListGizmo
是一个列表,而子类
SetGizmo
是一个集合,因此此设置实际上在实践中运行良好。但是静态类型检查器(如pyright)不知道这一点,因此它们(正确地)在此处显示错误:

class AbstractGizmo(ABC):

    def bloviate(self):
        return bloviate(self)  # Error: Type 'AbstractGizmo' cannot be assigned
                               # to type 'Set[Unknown] | List[Unknown]'
我是否可以通过某种方式向Python/pyright表明,本质上,“所有
AbstractGizmo
的实例都保证位于
Union[Set,List]
”中?我不明白这种语法

(请注意,在这个简单的示例中,我可以在每个子类上定义
bloviate()
,以避免出现问题。实际上,我有更多的方法和更多的包装器子类,因此如果我不能将它们适当地抽象为
AbstractGizmo
),我会得到一个组合爆炸,将
self
参数注释为与所需基本类型的功能相匹配:

来自输入导入协议
从abc进口abc
类HasLength(协议):#或者在本例中仅为'typing.size'
定义长度(自)->int:。。。
def bloviate(集合:HasLength):
print(f“让我告诉您有关我的{len(collection)}元素的更多信息”)
类抽象Gizmo(ABC):
def bloviate(自身:HasLength):
返回膨胀液(自身)
类ListGizmo(列表,AbstractGizmo):
通过
ListGizmo().bloviate()#这很好
请注意,mixin仍然可以与其他类型组合,而不会引发静态类型错误。但是,使用相应的方法会触发一个错误,包括运行时错误和静态类型检查错误

class IntGizmo(int,AbstractGizmo):
通过
IntGizmo().bloviate()#错误:对于类型为“Callable[[HasLength],Any]”的属性函数“bloviate”,自变量“IntGizmo”无效