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

一般类使用

以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. Nginx 防爬虫设置

    在conf下  vi 一个文件agent_deny.conf 添加如下内容 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|Http ...

  2. 聊聊docker那些端口问题

    今天来系统聊一聊docker的端口,常见的有容器内程序端口.容器端口.主机端口.Dockerfile中EXPOSE端口.docker-compose和docker run中的port等. 貌似很多端口 ...

  3. Servlet初级学习加入数据库操作(一)

    需要的源代码地址: https://url56.ctfile.com/f/34653256-527822631-2e255a(访问密码:7567) 将页面中的数据逐步替换为数据库管理 准备一个连接数据 ...

  4. UDP代码编写、操作系统发展史、多道技术、进程理论与代码层面创建、进程join方法与进程对象方法

    昨日内容回顾 socket基本使用 # 内置的模块 import socket s = socket.socket() # 默认是TCP协议 也可以切换为UDP协议 s.bind((ip,port)) ...

  5. Web开发之Cookie and Session

    会话 什么是会话? 简单说:用户开一个浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程就称之为一个会话. 会话过程要解决什么问题 每个用户在使用浏览器与服务器进行会话的过程 ...

  6. linux 安装mysql 可能遇到的小问题

    问题一. ./mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No ...

  7. 《剑指offer》面试题57. 和为s的两个数字

    问题描述 输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,则输出任意一对即可. 示例 1: 输入:nums = [2,7,11,15], tar ...

  8. office 下载(免费使用

    https://otp.landian.vip/zh-cn/download.html

  9. MySQL的学习记录 DAY03~

    小记:昨天打了新冠加强针,今天开始拉肚子,嗓子疼,超级难受~

  10. gin中如何记录日志和错误日志

    package main import ( "github.com/gin-gonic/gin" "io" "os" ) func main ...