小能豆

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

py

我正在编写一个通用类AnyStr,因此允许bytesstr

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

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


阅读 19

收藏
2025-01-01

共1个答案

小能豆

您应该有一个基类,其中共享方法适用于 和strbytes并利用常见行为(例如, 和 都str具有bytes长度,或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())。相反,因为您在评论中说过,调用方会提前知道他们是否想要bytesstr,他们会直接实例化MyStrMyBytes

2025-01-01