假设我想在集合和列表上定义包装器类,添加一些有用的方法,如下所示:
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
,我会得到一个组合爆炸。)
要正确地type mixin classes,请将} 匹配所需基类型的功能:
self
参数注释为^{请注意,mixin仍然可以与其他类型组合,而不会引起静态类型错误。但是,使用相应的方法会触发一个错误,包括运行时错误和静态类型检查错误
相关问题 更多 >
编程相关推荐