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

问题描述 投票:0回答:1

我正在

AnyStr
上编写一个泛型类,因此允许
bytes
str

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

在此类的(多个)方法内部,我想构造空字节或空字符串对象,

b''
''
,具体取决于类型参数。我怎样才能做到这一点?

python mypy python-typing
1个回答
1
投票

您应该有一个基类,其中的共享方法适用于

str
bytes
,这些方法利用共同行为(例如,
str
bytes
都具有长度,或者
str
bytes
可索引),以及两个提供特定行为实现的子类。为了强制子类提供这些特定行为(这样
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
,所以他们会直接实例化
MyStr
MyBytes

© www.soinside.com 2019 - 2024. All rights reserved.