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

一般类使用

以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使用泛型的更多相关文章

  1. 【Java心得总结四】Java泛型下——万恶的擦除

    一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...

  2. Python - typing 模块 —— TypeVar 泛型

    前言 typing 是在 python 3.5 才有的模块 前置学习 Python 类型提示:https://www.cnblogs.com/poloyy/p/15145380.html 常用类型提示 ...

  3. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  4. 自发行python版本制作(一)

    最近使用python开发一些小玩意,发现python实在很符合我的理念:轻量级,功能强大,开放. python是一种脚本语言,不像java那样需要沉重的编译过程.这使得python更显得轻巧灵便,可以 ...

  5. Python 基礎 - 文件的操作

    在來我們來玩一下文件操作,這個在未來工作上,也是會很常用到的功能 Python2.7中,可以用file()來打開文件,而在Python3中,一律都是用open(),接下來在當前目錄下,先建立一個空文件 ...

  6. [python实现设计模式]-5.迭代器模式-一起撸串嗨皮啦

    迭代器模式是一个我们经常使用但是出境不高的模式. 为啥捏?因为大部分的语言都帮我们实现了细节,我们不许关注他的实现就能用的很嗨皮了. 不管怎样.这也是个非常常用的模式. 俗话说得好,这个世界上没有事情 ...

  7. 【循序渐进学Python】14.数据库的支持

    纯文本只能够实现一些简单有限的功能.如果想要实现自动序列化,也可以使用 shelve 模块和 pickle 模块来实现.但是,如果想要自动的实现数据并发访问,以及更标准,更通用的数据库(databas ...

  8. Python基础s14-day1

    2016年7月23日"Python基础s14-Day1" Python是什么? Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/),是一种面向对象.直译式 ...

  9. Python简易聊天工具-基于异步Socket通信

    继续学习Python中,最近看书<Python基础教程>中的虚拟茶话会项目,觉得很有意思,自己敲了一遍,受益匪浅,同时记录一下. 主要用到异步socket服务客户端和服务器模块asynco ...

随机推荐

  1. Hadoop HA(高可用) 详细安装步骤

    什么是HA? HA是High Availability的简写,即高可用,指当当前工作中的机器宕机后,会自动处理这个异常,并将工作无缝地转移到其他备用机器上去,以来保证服务的高可用.(简言之,有两台机器 ...

  2. 初识python: 局部变量、全局变量

    定义: 全局变量:在函数一开始定义的变量(全局范围内都可以使用) 局部变量:在函数中定义的变量(只能在函数中使用) 局部变量,例: #局部变量 def chang_name(name): print( ...

  3. MySQL删除数据库或表(DROP DATABASE/table语句)

    DROP DATABASE [ IF EXISTS ] <数据库名> DROP table[ IF EXISTS ] <数据库表名> 语法说明如下: <数据库名>: ...

  4. IE8和IE9下textarea滚动选中的问题

    在IE8和IE9下如果textarea设置了样式overflow-y:auto;就不可以滚动选中了,应该样式写成overflow:auto;有了纵向滚动实际上就不会出现横向滚动的情况,也没有必要ove ...

  5. h5跳转高德地图

    <a href="https://uri.amap.com/marker?position=经度,纬度&name=所在的位置名称">高德地图</a>

  6. 《剑指offer》面试题66. 构建乘积数组

    问题描述 给定一个数组 A[0,1,-,n-1],请构建一个数组 B[0,1,-,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×-×A[i-1]×A[i+1]×-×A[n-1].不能使用 ...

  7. vue3代码setup中this为什么无效

    结论:setup并没有通过各种方式去绑定this 在vue2中,我们可以在optionsApi中调用this来指向当前组件的实例,但是在vue3的setup中并不能这样做,因为setup位于组件创建成 ...

  8. JavaCV的摄像头实战之一:基础

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<JavaCV的摄像头实战>系列 &l ...

  9. python08day

    内容回顾 数据类型的补充 str:pass tuple: (1)----->int count 计数 index 通过元组获取索引 list sort 排序从小到大 sort(reverse=T ...

  10. 学习JAVAWEB第十六天

    今天做了一个简单的登陆界面,HTML+CSS太不熟悉了,明天还得接着做