微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在泛型类中调用类型参数的构造函数

如何解决在泛型类中调用类型参数的构造函数

我正在编写一个基于 AnyStr 的泛型类,因此允许使用 bytesstr

class MyObject(Generic[AnyStr]):
   ...

在此类的(多个)方法中,我想根据类型参数构造空字节或空字符串对象,b''''。我该怎么做?

解决方法

您应该有一个基类,其中共享方法适用于 strbytes,它们利用了共同的行为(例如,strbytes 都具有长度,或者 strbytes 都可索引),以及两个子类,为特定行为提供实现。为了强制子类提供那些特定的行为(这样 mypy 可以假设对其特定方法的调用会在基类中成功),您可以在基类中创建一个等效的 @abstractmethod

这就是它的样子:

from abc import abstractmethod,ABC
from typing import AnyStr,Generic,final

class MyObject(ABC,Generic[AnyStr]):
    @classmethod
    @abstractmethod
    def empty(cls) -> AnyStr:
        pass

    def __init__(self,data: AnyStr):
        self.data: AnyStr = data

    # Example shared method.
    def is_empty(self) -> bool:
        # Assume that for the sake of the example we can't do `len(self.data) == 0`,and that we need
        # to check against `empty()` instead.
        return self.data == self.__class__.empty()

class MyStr(MyObject[str]):
    @classmethod
    @final
    def empty(cls) -> str:
        return ""

class MyBytes(MyObject[bytes]):
    @classmethod
    @final
    def empty(cls) -> bytes:
        return b""

我们将 empty() 设为类方法而不是实例方法,因为它不依赖于具有特定数据的实例来了解空的 str / bytes 是什么样子。

此外,我们使 empty() 成为最终方法,因此想要进一步提供特定行为的 MyStr 或 MyBytes` 的子类不会改变被认为是“空”的东西(因为有只有一件事可以被认为是空的)。

以上所有内容都将在 mypy --strict 下进行类型检查。

在调用方,他们永远不会实例化 MyObject[str]MyObject[bytes](事实上,mypy 会阻止这种情况,正如我们希望的那样,因为 MyObject 不会有 empty() 的实现)。相反,因为您在评论中说调用者会提前知道他们想要 bytes 还是 str,所以他们直接实例化 MyStrMyBytes

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。