【问题标题】:how to implement and annotate parent classmethod so that child methods return an instance of themselves?如何实现和注释父类方法,以便子方法返回自己的实例?
【发布时间】:2022-12-12 11:45:40
【问题描述】:

我有一个父类BaseBlob,它有几个子类LimitedProofIdProofIdTxId。父类实现一个 deserialize 类方法,该方法应返回其自身的一个实例。

我还有一个 Delegation 类,它接受一个 LimitedProofId。我特别想要我的如果我错误地传递了 BaseBlob 的另一个子实例,例如 ProofIdTxId,则会出错。

class BaseBlob:
    __init__(self, data: bytes):
        self.data = data

    @classmethod
    deserialize(class, stream: BytesIO) -> BaseBlob:
        return cls(stream.read(32))


class LimitedProofId(BaseBlob):
    pass


class TxId(BaseBlob):
    pass


class Delegation:
    def __init__(self, ltd_id: LimitedProofId):
        self.ltd_id = ltd_id

    def deserialize(self, stream: BytesIO) -> Delegation:
        ltd_id = LimitedProofId.deserialize(stream)
        return Delegation(ltd_id)

我的显示此代码的错误,因为如果认为 LimitedProofId.deserializeBaseBlob

error: Argument 1 to "Delegation" has incompatible type "BaseBlob"; expected "LimitedProofId"  [arg-type]

我已经看到类似问题的答案,这些问题使用 T = TypeVar('T', bound='BaseBlob') 实现允许子类的类型注释,但如果我这样做,我需要为 BaseBlob.deserialize 的返回类型和 @ 的第一个参数指定 T 987654338@,这违背了我对后者类型安全的目的。

有没有办法实现我想做的事情,而不必在所有子类上重新实现deserialize

【问题讨论】:

    标签: python type-hinting mypy


    【解决方案1】:

    Python 3.11 为此引入了Self 类型提示。 (PEP 673 更详细地描述了代码 Self 旨在简化,如果您还没有升级到 3.11。)

    from typing import Self
    
    
    class BaseBlob:
        def __init__(self, data: bytes):
            self.data = data
    
        @classmethod
        def deserialize(cls, stream: BytesIO) -> Self:
            return cls(stream.read(32))
    

    【讨论】:

    • 我不相信这适用于 classmethod
    猜你喜欢
    • 1970-01-01
    • 2017-11-22
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    相关资源
    最近更新 更多