(01)fastapi的基础学习——开启学习之路

前言

性能极高,可与 NodeJS, Go 媲美。(得益于Starlette和Pydantic)。

Starlette 是一个轻量级 ASGI 框架/工具包。它非常适合用来构建高性能的 asyncio 服务,并支持 HTTP 和 WebSockets。

官方网址:Starlette

Pydantic 是一个使用Python类型提示来进行数据验证和设置管理的库。Pydantic定义数据应该如何使用纯Python规范用并进行验证。

官方网址:https://pydantic-docs.helpmanual.io/

简单易懂,易于上手

1、设计的初衷就是易于学习和使用。不需要阅读复杂的文档。

2、良好的编辑器支持。支持自动完成,可以花更少的时间用于调试。

3、代码复用性强。

4、方便的 API 调试,生成 API 文档。

5、能提高开发人员两到三倍的开发速度。减少40%的人为出错几率。

一、基础环境的安装

Python 3.6+

FastAPI 站在这些巨人的肩膀上

  • Starlette :web部分
  • Pydantic :数据部分

可选依赖项:

Pydantic需要:

  • ujson - 比较快的 JSON 解析.
  • email_validator - email 校验.

Starlette需要:

  • requests - TestClient 需要.
  • aiofiles - FileResponse 或者 StaticFiles 需要.
  • jinja2 - 缺省模板配置需要.
  • python-multipart - 表单解析需要.
  • itsdangerous - SessionMiddleware 支持需要.
  • pyyaml - Starlette's SchemaGenerator 支持需要.
  • graphene - GraphQLApp 支持需要.
  • ujson - UJSONResponse 需要.

FastAPI / Starlette需要:

  • uvicorn - 加载和服务程序需要.
  • orjson - ORJSONResponse 需要.

1.2、安装

1、pip install fastapi

2、我们需要一个ASGI服务器,可以使用 Uvicorn 或 Hypercorn。

     pip install uvicorn

1.3 第一fastapi小案例

如图所示,本文所有的案例代码写在了casedemo中,并通过运行主要文件app.py文件实现功能的访问。代码如下所示:

案例1代码:

from fastapi import APIRouter
router = APIRouter()
# 这是我写的第一个测试用例。测试用例1
@router.get("/") #使用路由的方式实现了对/的请求
def read_root():return {"Hello": "World"}@router.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):return {"item_id": item_id, "q": q}

 app.py主文件

from fastapi import FastAPI
import uvicorn
from casedemo import demo1_casedemo1app = FastAPI()
app.include_router(demo1_casedemo1.router)
# 运行 FastAPI
if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8888)

启动的效果图如图所示

1.4 交互式API文档

我们访问以下两个地址,可获取自动生成的交互式API文档,并且当代码改动时文档会自动更新。方便我们的开发调试。

1、http://127.0.0.1:8000/docs (基于 Swagger UI)

2、http://127.0.0.1:8000/redoc (基于 ReDoc)

1.5 查询参数

声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数

@router.get("/demo2/read_items/")
async def read_item(skip: int = 0, limit: int = 10):return fake_items_db[skip : skip + limit]

 二、Pydantic做类型强制检查

FastAPI 基于 Pydantic ,Pydantic 主要用来做类型强制检查。参数赋值,不符合类型要求就会抛出异常。

对于 API 服务,支持类型检查非常有用,会让服务更加健壮,也会加快开发速度,因为开发者再也不用自己写一行一行的做类型检查。

我们用纯粹的,经典的Python来定义数据,用Pydantic来校验数据。

官方文档地址:https://pydantic-docs.helpmanual.io/

安装

pip install pydantic

 2.1 使用案例(BaseModel方式)

class User(BaseModel):id: intname: Optional[str] = "jack"signup_timestamp: datetime = Nonefriends: List[int] = []

观察到:

  • id 要求必须为 int
  • name 要求必须为 str, 且有默认值
  • signup_timestamp 要求为 datetime, 默认值为 None
  • friends 要求为 List,元素类型要求 int, 默认值为 []

 2.2 使用 Query 作为默认值

我们打算添加约束条件:即使 q 是可选的,但只要提供了该参数,则该参数值不能超过50个字符的长度。

具体可以查阅文献:FastAPI教程 查询参数和字符串校验_w3cschool

@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}if q:results.update({"q": q})return results

 2.3 完整的案例

from pydantic import ValidationError
from datetime import datetime
from typing import List
from pydantic import BaseModel
from typing import Optional
from fastapi import APIRouter, HTTPException  # 使用路由
router = APIRouter()fake_items_db = [# 本部分模拟的是一个数据库信息的列表{"name": "Foo", "description": "A foo item", "price": 10.5},{"name": "Bar", "description": "A bar item", "price": 20.0},{"name": "Baz", "description": "A baz item", "price": 30.0}
]
class User(BaseModel):id: intname: Optional[str] = "jack"signup_timestamp: datetime = Nonefriends: List[int] = []class UserLogin(BaseModel):username: strpassword: strclass Item(BaseModel):# 当你创建 Item 类的实例时,Pydantic 会自动验证传入的数据是否符合类定义的类型约束。name:strdescription: Optional[str] = None'''description: Optional[str] = Nonedescription 是一个可选的字符串类型字段,使用了 Optional[str]。Optional[str] 表示这个字段可以是一个字符串类型,也可以是 None。如果在创建 Item 实例时未提供 description,默认值为 None。'''price: floattax: Optional[float] = None@router.post("/demo2/items/")
async def create_item(item: Item):# print(item.dict())# print(fake_items_db)if item.name in fake_items_db:# print(item.name)# print(item)raise HTTPException(status_code=200, detail="Item already exists")fake_items_db.append(item)# print(fake_items_db)return fake_items_db@router.post("/demo2/logindemo2")
async def userlogin_requestlogin_demo2(userlogin: UserLogin):  # 接收 JSON 或表单数据if userlogin.username == "admin" and userlogin.password == "admin":print("当前进入到userlogin_requestlogindemo2函数中,用户名和密码正确")return {"status": 200, "msg": "登录成功"}else:print("当前进入到userlogin_requestlogindemo2函数中,用户名和密码错误")raise HTTPException(status_code=401, detail="用户名或密码错误")@router.post("/demo2/userdemo/")
async def demo2_userdemo(user:User):print(user)return user@router.get("/demo2/read_items/")
async def read_item(skip: int = 0, limit: int = 10):return fake_items_db[skip : skip + limit]

三、路径参数

3.1路径参数声明

我们可以用以下的方式来声明URL路径参数。

from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id):return {"item_id": item_id}

这里,路径参数item_id的值会直接作为实参item_id传递给函数read_item。

运行这个示例并访问:http://127.0.0.1:8000/items/foo,结果如下:

{"item_id":"foo"}

3.2路径参数的变量类型

基于标准的Python类型注释,你可以在路径函数中声明路径参数的变量类型

from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):return {"item_id": item_id}

这里,item_id被声明为int类型。 

运行代码并访问 http://127.0.0.1:8000/items/3,你会得到结果:

{"item_id":3}

注意这里函数接收到的数据是int类型的3,而不是字符串"3"。

也就是说,借助类型声明,FastAPI可以对Request内容自动进行数据解析和数据转换。

3.4 数据校验

如果访问 http://127.0.0.1:8000/items/foo,你会看到如下的错误:

{"detail": [{"loc": ["path","item_id"],"msg": "value is not a valid integer","type": "type_error.integer"}]
}

因为这里路径参数item_id的值是"foo",无法转换成int。

如果提供给item_id一个float类型的值,如4.2,也会发生类似的错误。

因此借助类型声明,FastAPI给了你自动进行数据校验的能力。返回结果里清晰的指出了具体错误内容,这非常有利于你的代码开发和调试。

所有的数据校验能力都是在Pydantic的底层支持下得以实现的。你可以利用通用的数据类型如str、float、bool或者其他更复杂的数据类型进行类型注释。

3.5 路径参数问题

在有些情况下,路径声明的顺序不同会影响访问结果,这里应该留意下。

from fastapi import FastAPI
app = FastAPI()
@app.get("/users/me")
async def read_user_me():return {"user_id": "the current user"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):return {"user_id": user_id}

这里路径 /users/me 应该在路径 /users/{user_id} 之前进行声明。否则,针对路径 /users/me 的访问就会被匹配到 /users/{user_id},因为"me"会被认为是路径参数 user_id 的值。 

3.6 路径参数的预定义值

我们可以使用Python Enum来声明路径参数的预定义值。

from enum import Enum
class ModelName(str, Enum):alexnet = "alexnet"resnet = "resnet"lenet = "lenet"

这里,我们声明了一个类ModelName,它继承自str(这样限制了值的类型必须是字符串类型)和Enum。

这里也给出了ModelName类属性的值。

使用示例如下:

from enum import Enum
from fastapi import FastAPI
class ModelName(str, Enum):alexnet = "alexnet"resnet = "resnet"lenet = "lenet"
app = FastAPI()
@app.get("/model/{model_name}")
async def get_model(model_name: ModelName):if model_name == ModelName.alexnet:return {"model_name": model_name, "message": "Deep Learning FTW!"}if model_name.value == "lenet":return {"model_name": model_name, "message": "LeCNN all the images"}return {"model_name": model_name, "message": "Have some residuals"}

这时路径参数model_name的类型是我们定义的枚举类ModelName。

我们可以访问可交互式文档 http://127.0.0.1:8000/docs 来快速进行接口验证。

3.7 路径参数中包含文件路径

当路径参数中包含文件路径时,比如 /files/{file_path},我们可以用声明file_path类型的方式进行支持。

/files/{file_path:path}

这里:path指出了file_path可以匹配任何文件路径。

from fastapi import FastAPI
app = FastAPI()
@app.get("/files/{file_path:path}")
async def read_file(file_path: str):return {"file_path": file_path}

3.8 路径操作的其他参数

我们可以在路径操作中添加其他参数,比如标签列表。

@app.post("/items/", response_model=Item, tags=["items"])
async def create_item(*, item: Item):return item@app.get("/items/", tags=["items"])
async def read_items():return [{"name": "Foo", "price": 42}]@app.get("/users/", tags=["users"])
async def read_users():return [{"username": "johndoe"}]

也可以添加summarydescription参数。

@app.post("/items/",response_model=Item,summary="Create an item",description="Create an item with all the information, name, description, price, tax and a set of unique tags",
)

以及文档字符串。 

@app.post("/items/", response_model=Item, summary="Create an item")
async def create_item(*, item: Item):"""Create an item with all the information:- **name**: each item must have a name- **description**: a long description- **price**: required- **tax**: if the item doesn't have tax, you can omit this- **tags**: a set of unique tag strings for this item"""return item

 或者deprecated参数表示该路径操作已过期。

@app.get("/elements/", tags=["items"], deprecated=True)
async def read_elements():return [{"item_id": "Foo"}]

四、请求参数

本部分已经在前面一二三中进行了展示,具体可以查看

FastAPI 基础学习(五) 请求参数 - 麦克煎蛋 - 博客园

五、Request Body

5.1 单个Request Body

FastAPI 基础学习(六) Request Body(I) - 麦克煎蛋 - 博客园

FastAPI 教程翻译 - 用户指南 5 - 请求主体_fastapi获取的body转成dict-CSDN博客

5.2 多个Request Body

我们可以同时声明多个Request Body参数。

from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):name: strdescription: str = Noneprice: floattax: float = Noneclass User(BaseModel):username: strfull_name: str = None@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item, user: User):results = {"item_id": item_id, "item": item, "user": user}return results

这两个参数(item、user)类型都是Pydantic数据模型。 

* 用于强制在函数参数中使用关键字参数。这意味着在调用 update_item 时,item_id 必须以关键字的形式传递,而不能作为位置参数。这有助于提高代码的可读性和明确性。

六、参数附加信息

6.1 请求参数附加信息

FastAPI 基础学习(八) 参数附加信息 (一) - 麦克煎蛋 - 博客园

6.1.1 导入Query模块

from fastapi import Query

6.1.2基于Query模块声明缺省值

可选参数声明q: str = Query(None)  # 等同于  
q: str = None
缺省值参数声明q: str = Query("query")  # 等同于  q: str = "query"
必选参数声明q: str = Query(...)  # 等同于 
q: str

6.1.3 添加附加信息

q: str = Query(None, max_length=50)  # 限制q的最大长度不超过50
主要用于字符串参数的附加信息:min_length:最小长度
max_length:最大长度
regex:正则表达式
主要用于自动化文档的附加信息:title:参数标题
description:参数描述信息
deprecated:表示参数即将过期
特殊附加信息:alias:参数别名
例如:http://127.0.0.1:8000/items/?item-query=foobaritems

 item-query并不是一个合法的Python变量名称,Python内部会对它进行转换,为了匹配到正确的参数变量我们就需要使用参数别名。

完整案例

from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query(None,alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,regex="^fixedquery$",deprecated=True)
):results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}if q:results.update({"q": q})return results

6.2 请求参数列表

FastAPI基于Query模块可以支持请求参数列表,例如请求参数q可以在URL中出现多次:

http://localhost:8000/items/?q=foo&q=bar

对应代码如下:

from typing import List
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: List[str] = Query(None)):query_items = {"q": q}return query_items

返回结果内容为:

{"q": ["foo","bar"]
}

 当然这里Query也支持请求参数列表的缺省值设置。

from typing import List
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: List[str] = Query(["foo", "bar"])):query_items = {"q": q}return query_items

我们也可以用list代替List[str],但这样的话FastAPI就无法校验列表内容了。 

from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: list = Query(None)):query_items = {"q": q}return query_items

 6.3 路径参数附加信息

FastAPI 基础学习(九) 参数附加信息 (二) - 麦克煎蛋 - 博客园

6.3.1 导入Path模块

from fastapi import Path

6.3.2 添加附加信息

所有适用于请求参数的附加信息同样适用于路径参数,如title等。

item_id: int = Path(..., title="The ID of the item to get") 

注意,路径参数在URL里是必选的,因此Path的第一个参数是...,即使你传递了None或其他缺省值,也不会影响参数的必选性。

6.3.3 代码示例

@router.get("/demo1/items/{item_id}")
async def read_items_demo1(q: str, item_id: int = Path(..., title="The ID of the item to get")
):results = {"item_id": item_id}if q:results.update({"q": q})return results

6.4 路径参数、请求参数顺序问题

6.4.1不带缺省值的参数应放在前面

如果把带有缺省值的参数放在了不带缺省值的参数前面,Python会发出运行警告。

因此在实际使用时,我们应当把不带缺省值的参数放在前面,无论这个参数是路径参数还是请求参数。

from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(q: str, item_id: int = Path(..., title="The ID of the item to get")
):results = {"item_id": item_id}if q:results.update({"q": q})return results

 FastAPI根据参数名称、类型以及声明方法(如Query、Path等等)来识别具体参数意义,并不关心参数顺序。

6.4.2 参数排序的技巧

通过传递 * 作为第一个参数,就解决了上面的参数顺序问题。

from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(*, item_id: int = Path(..., title="The ID of the item to get"), q: str
):results = {"item_id": item_id}if q:results.update({"q": q})return results

Python并不会对 * 做任何操作。但通过识别 *,Python知道后面所有的参数都是关键字参数(键值对),通常也叫kwargs,无论参数是否有默认值。 

6.5 数字类型参数的校正

借助Query、Path等模块你可以声明对字符串类型参数的校验,同样的,也可以实现对数字类型参数的校验功能。附加参数信息说明:gt: 大于(greater than)
ge: 大于或等于(greater than or equal)
lt: 小于(less than)
le: 小于或等于( less than or equal)

具体示例如下:

from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(*,item_id: int = Path(..., title="The ID of the item to get", gt=0, le=1000),q: str,
):results = {"item_id": item_id}if q:results.update({"q": q})return results

数字校验同样也适用于float类型的参数。

from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(*,item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),q: str,size: float = Query(..., gt=0, lt=10.5)
):results = {"item_id": item_id}if q:results.update({"q": q})return results

七、Pydantic复杂模型

FastAPI 基础学习(十) Pydantic复杂模型 - 麦克煎蛋 - 博客园

7.1 Pydantic模型的附加信息

与前面讲过的Query、Path、Body类似,我们也可以为Pydantic模型添加附加信息,基于模块Field。

Field模块的参数与Query、Path、Body等相同。

from pydantic import BaseModel, Field
from fastapi import Body, FastAPI
from fastapi import APIRouter
router = APIRouter()class Item(BaseModel):name: strdescription: str = Field(None, title="The description of the item", max_length=300)price: float = Field(..., gt=0, description="The price must be greater than zero")tax: float = None@router.put("/demo3/items/{item_id}")
async def update_item(*, item_id: int, item: Item = Body(..., embed=True)):results = {"item_id": item_id, "item": item}return results

7.2 模型的嵌套

任意嵌套深度的Pydantic模型,我们都可以进行定义、校验、自动文档化和灵活使用。 

比如list,dict,tuple,set等等。

from typing import Dict
from fastapi import FastAPIapp = FastAPI()@app.post("/index-weights/")
async def create_index_weights(weights: Dict[int, float]):return weights

7.3 复杂的数据类型 

FastAPI 基础学习(十一) 复杂数据类型 - 麦克煎蛋 - 博客园

八、Cookie操作

FastAPI 基础学习(十二) Cookie操作 - 麦克煎蛋 - 博客园

基于Query、Path等模块同样的模式,我们可以利用Cookie模块来声明cookies。Cookie是Query、Path的姐妹类,它们都继承自Param类。同样我们也可以便捷的定义Cookie模块的参数信息。

九、Header操作

FastAPI 基础学习(十三) Header操作 - 麦克煎蛋 - 博客园

基于Query、Path、Cookie等模块同样的模式,我们可以利用Header模块来声明headers。我们可以用定义其他模块参数同样的方式,便捷的定义Header模块的参数信息。

Header是Query、Path、Cookie的姐妹类,它们都继承自Param类。

十、Response自定义状态码

FastAPI 基础学习(十四) Response自定义状态码 - 麦克煎蛋 - 博客园

十一、直接使用Request

参考文献

FastAPI 基础学习(一)概述 - 麦克煎蛋 - 博客园

FastAPI 基础学习(二)开发环境安装 - 麦克煎蛋 - 博客园

FastAPI 基础学习(三) Pydantic 做类型强制检查 - 麦克煎蛋 - 博客园

FastAPI教程 查询参数和字符串校验_w3cschool

FastAPI 基础学习(四) 路径参数 - 麦克煎蛋 - 博客园

FastAPI 基础学习(五) 请求参数 - 麦克煎蛋 - 博客园

FastAPI 基础学习(七) Request Body(II) - 麦克煎蛋 - 博客园

FastAPI 基础学习(八) 参数附加信息 (一) - 麦克煎蛋 - 博客园
FastAPI 基础学习(九) 参数附加信息 (二) - 麦克煎蛋 - 博客园

FastAPI 基础学习(十) Pydantic复杂模型 - 麦克煎蛋 - 博客园

FastAPI 基础学习(十一) 复杂数据类型 - 麦克煎蛋 - 博客园

FastAPI 基础学习(十二) Cookie操作 - 麦克煎蛋 - 博客园

FastAPI 基础学习(十三) Header操作 - 麦克煎蛋 - 博客园

FastAPI 基础学习(十四) Response自定义状态码 - 麦克煎蛋 - 博客园

FastAPI 基础学习(十五) 直接使用Request - 麦克煎蛋 - 博客园

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/451399.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

摇人摇人, JD内推岗位(社招+校招)

摇人摇人, 有找工作的家人们看过来啊~ 虚位以待, 快到碗里来 算法开发工程师岗 京东云 北京|T7, 5-10年 岗位职责: 参与基于RAG知识库平台和ChatBI产品打造和商业化落地,进行相关技术:包括OCR、文档拆分、意图理解、多轮对话、NL2SQL、Embed…

idea删除git历史提交记录

前言:此文章是我在实际工作中有效解决问题的方法,做记录的同时也供大家参考! 一、 首先,通过idea的终端或系统的cmd控制台,进入到你的项目文件根目录,idea终端默认就是项目根目录。 二、确保你当前处于要删…

Bluetooth Channel Sounding中关于CS Step及Phase Based Ranging相应Mode介绍

目录 BLE CS中Step定义 BLE CS中交互的数据包/波形格式 BLE CS中Step的不同Mode BLE CS中Step的执行过程 Mode0介绍 Mode0 步骤的作用 Mode0步骤的执行过程 Mode0步骤的执行时间 Mode0步骤的时间精度要求 Mode2介绍 Mode2步骤的作用和执行过程 Mode2步骤的执行时间 B…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor (官方链接 https://microsoft.github.io/monaco-editor/)是一个由微软开发的功能强大的在线代码编辑器,被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

Linux 阻塞和非阻塞 IO 实验

阻塞和非阻塞 IO 是 Linux 驱动开发里面很常见的两种设备访问模式,在编写驱动的时候一定要考虑到阻塞和非阻塞。本章我们就来学习一下阻塞和非阻塞 IO,以及如何在驱动程序中处理阻塞与非阻塞,如何在驱动程序使用等待队列和 poll 机制。 阻塞和…

【机器学习】聚类算法|KMeans实现流程|SSE误差平法和|SC轮廓系数法|顾客数据聚类分析案例

文章目录 聚类算法聚类算法简介聚类算法分类 聚类算法API案例 使用KMeans模型数据探索聚类 KMeans实现流程***模型评估方法误差平方和 SSE(The sum of squares due to error)“肘”方法 (Elbow method) - K值确定 SC轮廓系数法(Silhouette Coefficient)聚…

微服务--OpenFeign【重点】

如果哪天 我们硬编码写的接口变了,只要写过该接口的 都要改,太麻烦了, 所以 就用 OpenFeign 来解决这个麻烦 了解: SimpleClientHttpRequestFactory和 HttpComponentsClientHttpRequestFactory 都是Spring框架中用于创建ClientH…

sentinel原理源码分析系列(六)-统计指标

调用链和统计节点构建完成,进入统计指标插槽,统计指标在最后执行的,等后面的插槽执行完,资源调用完成了,根据资源调用情况累计。指标统计是最重要的插槽,所有的功能都依靠指标数据,指标的正确与…

尤雨溪都点赞的表单校验解决方案,到底多么强

尤雨溪都点赞的表单校验解决方案,到底多么强 如果你是 Vue 开发者,那么 Vorms 绝对是你不能错过的表单验证利器。本文将带你快速了解 Vorms 的基本功能、特点和如何简单使用它提升你的开发体验。 软件简介 Vorms 是一个基于 Vue 3 组合式 API 的表单验证…

STL——string类

前言 从本篇博客开始,就正式来介绍STL的正式内容,STL在C中的学习中非常重要,具有举足轻重的地位,这块儿内容会给我们提供很多现成的接口,可以大大简化我们的代码,我们之前用C语言写的代码将会被极大地简化…

【数据分享】全国能源-电力平衡表(2000-2020年)

数据介绍 一级标题指标名称单位能源电力可供量亿千瓦小时能源电力生产量亿千瓦小时能源水电生产电力量亿千瓦小时能源火电生产电力量亿千瓦小时能源核电生产电力量亿千瓦小时能源风电生产电力量亿千瓦小时能源电力进口量亿千瓦小时能源电力出口量亿千瓦小时能源电力能源消费总量…

007、链表的回文结构

0、题目描述 链表回文结构 1、法1 一个复杂的问题可以拆解成几个简单的问题,找中间节点和逆置链表(翻转链表)之前都做过。 class PalindromeList { public://1、找中间节点ListNode* FindMid(ListNode* A){if (A nullptr || A->next …

设计模式03-装饰模式(Java)

4.4 装饰模式 1.模式定义 不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。 2.模式结构 抽象构件角色 :定义一个抽象接口以规范准备接收附加责任的对象。客户端可以方便调用装饰类和被装饰类…

基于STM32的电动汽车遥控器设计

引言 本项目设计了一个基于STM32的电动汽车遥控器,能够通过无线通信(如蓝牙或射频模块)控制电动汽车的前进、后退、左右转向等动作。该遥控器采用按键或摇杆操作,并通过无线模块将控制指令发送给汽车控制端,实现远程操…

吴恩达深度学习笔记(8)

计算机视觉 包括:图像分类也叫做图像识别、目标检测等 一个小的图像可能1M,但是他的像素是一个超级大向量,如果直接深度学习那么运算量会很大,因此需要运用卷积运算。 卷积运算是卷积神经网络的基础单元之一。下面用边缘检测理…

FastGPT本地开发 之 通过Navicat管理MongoDB、PostgreSQL数据库

1. 背景 前期已经完成FastGPT的本地化部署工作,通过Docker启动FastGPT的相关容器即可运行。(共6个容器) 2.本地化开发 2.1 前置依赖 2.2 源码拉取 git clone gitgithub.com:labring/FastGPT.git2.3 数据库管理 本地化运行的FastGPT使用…

leetcode73矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2: 输入&…

【含开题报告+文档+PPT+源码】基于SpringBoot和Vue的编程学习系统

开题报告 随着信息技术的迅猛发展和数字化转型的深入推进,编程技能已经成为现代社会中不可或缺的一项基本能力。无论是软件开发、数据分析还是人工智能等领域,编程都扮演着至关重要的角色。因此,培养和提高编程技能对于个人职业发展和社会创…

eNSP静态路由

1、实现全网通,考虑环形拓扑的优势。 R12: [Huawei]interface GigabitEthernet 0/0/0 [Huawei-GigabitEthernet0/0/0]ip address 192.168.1.1 24[Huawei]interface GigabitEthernet 0/0/1 [Huawei-GigabitEthernet0/0/1]ip address 192.168.2.1 24[Huawei]interfa…

软件设计模式------工厂方法模式

工厂方法模式(Factory Method Pattern),又称工厂模式,也叫虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Pactory Pattern),属于类创建型模式。 我们知道…