首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >泛型是python中的抽象类吗?

泛型是python中的抽象类吗?
EN

Stack Overflow用户
提问于 2022-12-01 20:48:39
回答 1查看 30关注 0票数 1

我正在尝试创建一个基类,它适用于应用程序中的任何CRUD,我看到了以下实现:

代码语言:javascript
运行
复制
ModelType = TypeVar("ModelType", bound=Base)
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
代码语言:javascript
运行
复制
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
    def __init__(self, model: Type[ModelType]):
        """CRUD object with default methods to Create, Read, Update,
        Delete (CRUD).
        **Parameters**
        * `model`: A SQLAlchemy model class
        * `schema`: A Pydantic model (schema) class
        """
        self.model = model

    '...crud methods'`

泛型是定义抽象类的一种方法,包含指定的对象(在本例中是ModelType、CreateSchemaType、UpdateSchemaType),或者泛型的用途是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-12-01 21:34:01

如果你的问题是关于typing.Generic的目的,我建议你阅读佩普484。它有一个专门讨论用户定义的泛型类的部分,并提供了一些专门用于此的示例,但整个文档值得阅读IMHO。如果您不确定泛型类型的整个概念,维基百科关于参数多态性通用程序设计的文章甚至值得浏览。

简单地说,您可以使用Generic基类以泛型方式定义自己的类,即针对一个或多个类型参数进行参数化。这些类型参数是通过typing.TypeVar构造的。值得注意的是,在大多数情况下,这些事情只与类型安全相关,而Python本身并没有真正强制这样做。相反,静态类型检查器(大多数IDE都有内置的)处理这些事情。

至于您的示例,完全有可能以通用的方式定义类,从而改进您自己的编码体验,因为IDE可能会给您提供有用的自动建议和警告。如果您在整个类的其他地方使用类型变量,这才会真正变得有用。示例:

代码语言:javascript
运行
复制
from typing import Generic, TypeVar


class Base:
    pass


ModelType = TypeVar("ModelType", bound=Base)


class CRUDBase(Generic[ModelType]):
    def __init__(self, model: type[ModelType]):
        self.model = model

    def get_model_instance(self) -> ModelType:
        return self.model()


class Sub(Base):
    def foo(self) -> None:
        print("hi mom")


if __name__ == "__main__":
    crud_a = CRUDBase(Sub)
    crud_b = CRUDBase(Base)
    a = crud_a.get_model_instance()
    b = crud_b.get_model_instance()
    a.foo()
    b.foo()  # error

mypy这样的好类型检查器会知道,aSub类型,因此有foo方法,而bBase类型,因此没有。从我们注释CRUDBase的方式,它就会知道这一点。

例如,PyCharm与此作斗争(不知道原因)。幸运的是,我们可以通过显式类型注释来帮助它,因为我们将CRUDBase定义为泛型类型:

代码语言:javascript
运行
复制
...
    crud_a: CRUDBase[Sub] = CRUDBase(Sub)
    crud_b: CRUDBase[Base] = CRUDBase(Base)
    a = crud_a.get_model_instance()
    b = crud_b.get_model_instance()
    a.foo()
    b.foo()  # PyCharm marks `foo` and complains

注意,到目前为止,对于我们的CRUDBase还没有什么特别的“抽象”。它是完全独立的,并且像这样运作(虽然还不是很有用)。

如果您希望类是一个抽象基,而不是直接实例化,abc模块将为您提供所需的工具。您可以在它上定义一个抽象基类和抽象方法,所有子类都必须实现它。但我认为现在很清楚,这是一个不同的概念。其思想是抽象类不是要实例化的,而是它的子类。

我希望这能帮助你指出一些有用的方向。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74647999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档