python使用泛型

所谓的泛型, 就是将数据类型作为参数进行传递, 即在我们用的时候确定数据类型, 这是一种在面向对象语言中经常使用的特性

一般类使用

以SQLAlchemy举例

比如: 我们统一写个将数据保存到数据库的接口, 只有将 数据库链接 表对象 数据传入即可, 返回的是 表对象的实例, 为了让IDE可以识别返回对象, 我们可以使用泛型
这里需要用到:

  1. typingTypeVarType
    TypeVar是类型变量, 主要用于泛型类型与泛型函数定义的参数, 第一个参数是名称, bound参数用于规定该类型为 bound值的子类
    Type[C]的形式为协变量, 表明 C的所有子类都应 使用C相同的 构造器签名 及 类方法签名, 假如我们需要返回泛型类型的话, 需要用到

    更多使用方法, 见: typing使用

  2. 使用了 pydantic规范要创建数据的类型

    关于 pydantic的一般使用, 见: Pydantic使用

from typing import TypeVar, Type
from sqlalchemy.orm import Session
from pydantic import BaseModel
from orm.models import Category
from orm.schemas import WriteCategoryModel

定义类型
ModelT = TypeVar("ModelT")
DataT = TypeVar("DataT", bound=BaseModel)  # bound表明该类为BaseModel的子类

"""
为节省空间, 表结构和模型不展示
"""
def create_category(session: Session, data: WriteCategoryModel) -> Type[Category]:
    cate_obj = save_one_to_db(session=session, model_class=Category, data=data)
    return cate_obj

def save_one_to_db(session: Session, model_class: ModelT, data: DataT) -> ModelT:
"""
    保存一条到数据库
    :param session: SQLAlchemy Session
    :param model_class: sqlalchemy模型类
    :param data: pydantic模型对象
    :return: 对应sqlalchemy模型类的对象
"""
    try:
        obj = model_class(**data.dict())
        session.add(obj)
        session.commit()
        # 手动将 数据 刷新到数据库
        session.refresh(obj)
        return obj

    except Exception as e:
        # 别忘记发生错误时回滚
        session.rollback()
        raise e

pydantic使用

在使用pydantic时, 亦可以使用泛型

比如: 在 FastAPI中返回统一返回格式为:

{
   "status": true,
   "msg": "success",
   "data": ...

}

我们的 data可能是列表或对象, 而且对应的 pydantic模型也不一样, 这时我们就可以使用泛型了

代码:

from typing import List, Optional, Generic, TypeVar

from fastapi import APIRouter, status, HTTPException
from pydantic import BaseModel
from pydantic.generics import GenericModel

router = APIRouter(prefix="/test", tags=["测试泛型"])

为了方便, 在这里定义pydantic模型
DataT = TypeVar("DataT")

class GenericResponse(GenericModel, Generic[DataT]):
"""
    通用返回数据
"""
    status: bool
    msg: str
    data: Optional[DataT] = None  # 可能连data都没有
    # 设置response_model_exclude_unset=True即可

class BookModel(BaseModel):
    id: int
    name: str

伪数据
fake_book_data = [
    {"id": 1, "name": "book1"},
    {"id": 2, "name": "book2"},
    {"id": 3, "name": "book3"},
    {"id": 4, "name": "book4"},
    {"id": 5, "name": "book5"},
]

@router.get("/books", response_model=GenericResponse[List[BookModel]])
def get_books():
    return {
        "status": True,
        "msg": "获取成功",
        "data": fake_book_data
    }

@router.get("/books/{bid}", response_model=GenericResponse[BookModel])
def retrieve_book(bid: int):
    for item in fake_book_data:
        if item.get("id") == bid:
            return {
                "status": True,
                "msg": "获取成功",
                "data": item
            }
    # 不存在
    raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="该书不存在")

访问 /docs页面, 成功通过测试

python使用泛型

Original: https://www.cnblogs.com/lczmx/p/15899969.html
Author: 403·Forbidden
Title: python使用泛型

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581323/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java多线程基础入门

    任务? 程序? 进程 Process?执行程序的一次执行过程,是一个动态的概念。是系统资源分配的单位 线程 Thread?一个进程中可以包含若干个线程,进程中至少有一个线程。线程是…

    Java 2023年6月9日
    068
  • 引入『客户端缓存』,Redis6算是把缓存玩明白了…

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处。 哈喽大家好啊,我是没更新就是在家忙着…

    Java 2023年6月5日
    087
  • Eclipse画UML图

    1.AmaterasUML的安装 参考Eclipse中安装AmaterasUML就可以画UML图了。 方式1:安装AmaterasUML插件(推荐) 方式2:将下载好的jar包放入…

    Java 2023年6月15日
    085
  • kafka小记

    1.kafka介绍 Kafka 是一个分布式流媒体平台,类似于消息队列或企业消息传递系统。kafka官网:http://kafka.apache.org/ kafka介绍-名词解释…

    Java 2023年6月9日
    074
  • maven打包scala+java工程

    在 scala和java混合编程的时候,需要添加一些额外的配置到pom中,才能将scala文件的class加到最终的jar中 打包的命令 Original: https://www…

    Java 2023年5月29日
    063
  • JAXB 使用记录

    参考资料 什么是 JAXB ? 开源中国: JAXB(Java Architecture for XML Binding简称JAXB)允许Java开发人员将Java类映射为XML表…

    Java 2023年6月9日
    071
  • 加工生产调度 贪心算法 c++

    某工厂收到了 n n 个产品的订单,这 n n 个产品分别在 A,B A ,B 两个车间加工,并且必须先在 A A 车间加工后才可以到 B B 车间加工。某个产品 i i 在 A,…

    Java 2023年6月5日
    063
  • java创建对象的5种方式

    1、使用new关键字 2、利用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法 3、…

    Java 2023年6月7日
    040
  • 反射

    反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。 从java基础的阶段我们了解到,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我…

    Java 2023年6月6日
    079
  • Vue学习之——–深入理解Vuex之多组件共享数据(2022/9/4)

    在上篇文章的基础上:Vue学习之——–深入理解Vuex之getters、mapState、mapGetters 1、在state中新增用户数组 …

    Java 2023年6月14日
    094
  • JMeter 逻辑控制之IF条件控制器

    逻辑控制之IF条件控制器 测试环境 JMeter-5.4.1 循环控制器介绍 添加While Controller 右键线程组->添加->逻辑控制器->While…

    Java 2023年6月16日
    076
  • Java8 新特性学习

    1、接口中的默认方法 Java8中允许接口中包含具有具体实现的方法,这种方法被称为”默认方法”,使用default关键字修饰。 如: public inte…

    Java 2023年6月8日
    077
  • Hexo 搭建个人博客

    Hexo 1、hexo是什么? Hexo是一个快速、简洁且高效的博客框架。可以把用户的markdown文件,按照指定的主题解析成静态网页。 作用:可以快递搭建个人博客。配置着git…

    Java 2023年6月5日
    094
  • (转)java术语(PO/POJO/VO/BO/DAO/DTO)

    转自:http://blog.csdn.net/gaoyunpeng/article/details/2093211 PO(persistant object) 持久对象在o/r …

    Java 2023年5月29日
    0139
  • Redis常用数据结构及应用场景

    1. 概述 Redis 一个开源的基于键值对(Key-Value)NoSQL 数据库。使用 ANSIC 语言编写、支持网络、基于内存但支持持久化。性能优秀,并提供多种语言的 API…

    Java 2023年6月5日
    062
  • Spring框架中使用了哪些设计模式及应用场景

    1、工厂模式 2、模板模式 3、代理模式 4、策略模式 5、单例模式 6、观察者模式 7、适配器模式 8、装饰者模式 Original: https://www.cnblogs.c…

    Java 2023年6月14日
    061
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球