如何将类属性设置为类方法返回类型?

Posted

技术标签:

【中文标题】如何将类属性设置为类方法返回类型?【英文标题】:How to set class property as class method return type? 【发布时间】:2021-12-27 09:16:03 【问题描述】:

我有一个类 A,它有一个类方法并将它的类属性作为返回类型。

A 得到了一个继承自 A 类的 B 类。

如何在A中设置get_instance返回类型并通知B获取正确的类型?

# typings.py
from typing import TypeVar, Type

AType = TypeVar("AType", bound="A")

T = TypeVar("T", int, str)


class A:
    TYPE = int

    @classmethod
    def get_instance(cls: Type[AType]) -> "AType.TYPE":
        return cls.TYPE()


class B(A):
    TYPE = str


a = B.get_instance()

reveal_type(a)

mypy typings.py

typings.py:12: error: Name "AType.TYPE" is not defined
typings.py:17: error: Incompatible types in assignment (expression has type "Type[str]", base class "A" defined the type as "Type[int]")
typings.py:22: note: Revealed type is "Any"

【问题讨论】:

cls.TYPE 可以更改为任何内容。所以除了Any 以外的其他描述都是不正确的,恕我直言。 你有一个错字 - get_instace 应该是 get_instance 您是否需要A 成为具有具体TYPE 的具体类? @VPfB Any 是对的,但是当我调用子类get_instance 方法时cls.TYPE 是固定的 @match 已修复,谢谢 【参考方案1】:TYPE

参数化 通过创建类Generic。这允许引用类属性TYPE 和具有相同类型变量的返回类型:

from typing import TypeVar, Type, Generic

T = TypeVar("T", str, int)


class Base(Generic[T]):
    TYPE: Type[T]

    @classmethod
    def get_instance(cls: "Type[Base[T]]") -> "T":
        return cls.TYPE()

请注意,这会阻止直接设置 TYPE。需要单独的通用 Base 和具体的 A 定义。

class A(Base[int]):
    TYPE = int

class B(Base[str]):
    TYPE = str

【讨论】:

以上是关于如何将类属性设置为类方法返回类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Roslyn 为类中具有特定返回类型的所有属性添加 JsonIgnore 属性?

将属性类型设置为类的类型

存储过程为列返回值,但 FromSqlRaw 为类属性返回 null

将类序列化为单个无属性元素,其内容设置为一个属性

如何将类属性设置为 Symfony2 表单输入

两张图示轻松看懂 UML 类图