gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 06:50:11 24 4
gpt4 key购买 nike

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

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 参数注释为 Protocol匹配所需基本类型的功能:

from typing import Protocol
from abc import ABC

class HasLength(Protocol): # or just `typing.Sized` in this case
def __len__(self) -> int: ...

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

class AbstractGizmo(ABC):
def bloviate(self: HasLength):
return bloviate(self)

class ListGizmo(list, AbstractGizmo):
pass

ListGizmo().bloviate() # this is fine

请注意,mixin 仍然可以与其他类型组合而不会引发静态类型错误。但是,使用相应的方法会触发运行时和静态类型检查的错误。

class IntGizmo(int, AbstractGizmo):
pass

IntGizmo().bloviate() # error: Invalid self argument "IntGizmo" to attribute function "bloviate" with type "Callable[[HasLength], Any]"

关于python - 我可以限制 Python 中子类的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66462192/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com