【Python开发】FastAPI 02:请求参数—路径参数、查询参数

news2024/11/25 22:55:38

进行接口请求时,请求参数是重中之重了!请求参数指客户端向服务端发送请求时,需要传递给服务端的参数,包括路径参数、查询参数、请求体等。举个例子,如果客户端想要获取某个用户的信息,可以向服务端发送一个 GET 请求,并在请求中传递用户的 ID,这个 ID 就是请求参数。本篇文章介绍路径参数和查询参数。

目录

1 基础_路径参数

1.1 声明路径参数

1.2 声明路径参数声明的类型

1.3 路径操作顺序

1.4 预设值

① 创建一个 Enum 类

② 声明路径参数

③ 使用 Python 枚举类型

1.5 包含路径的路径参数

2 基础_查询参数

2.1 声明查询参数

2.2 默认值

2.3 可选参数

2.4 类型转换

3 数值校验_查询参数

3.1 Query 使用

3.2 通过 Query 校验

① default—默认值

② max_length/min_length—字符最大/小长度

③ regex—正则表达式

④ 声明必需参数

⑤ 声明更多元数据

3.3 查询参数设定为列表/多个值

① List[str]

② list

4 数值校验_路径参数

4.1 Path 使用

4.2 按需对参数排序

4.3 通过 Path 校验

① ge—大于等于

② gt—大于,le—小于等于

③ 总结


1 基础_路径参数

1.1 声明路径参数

首先简单来声明下路径参数(使用与 Python 格式化字符串相同的语法):

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 传递给你的函数。此时 item_id 不限制类型,输入字符串还是数字均可,不过最终都会被后台转化成字符串。

运行示例并访问 http://127.0.0.1:8000/items/yinyu,将会看到如下响应 👇

若访问 http://127.0.0.1:8000/items/88 响应如下,可看到 88 已转化为字符串 "88"

1.2 声明路径参数声明的类型

然后简单声明下路径参数声明的类型(使用标准的 Python 类型标注):

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

该处的声明类型可以理解为限制类型,也就说该路径参数(查询参数相同)声明类型后,你实际在请求该路径时,只能按照提前声明好的类型进行请求。

此时访问 http://127.0.0.1:8000/items/88,响应正常,88 即为 int 类型。

若此时访问 http://127.0.0.1:8000/items/yinyu,将会返回报错信息,因为 yinyu 是字符串类型,而不是  int 类型,这就是声明了类型的作用 👇

所有的数据校验都由 Pydantic 在幕后完成。

你可以使用同样的类型声明来声明 str、float、bool 以及许多其他的复合数据类型。

📌 文档

此时访问 http://127.0.0.1:8000/docs,将看到自动生成的交互式 API 文档:

1.3 路径操作顺序

在创建路径操作时,会发现有些情况下路径是相同的。

比如:/users/me,假设它用来获取关于当前用户的数据;/users/{user_id} ,假设它用来通过用户 ID 获取关于特定用户的数据。

由于路径操作是按顺序依次运行的,你需要确保路径 /users/me 声明在路径 /users/{user_id} 之前!

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/{user_id} 的路径还将与 /users/me 相匹配,"认为"自己正在接收一个值为 "me" 的 user_id 参数。

1.4 预设值

有时只需要给路径参数传递几个常用并且固定的有效值,那么我就可以通过枚举来定制预设值。

① 创建一个 Enum 类

首先导入 Enum 并创建一个继承自 str Enum 的子类,通过从 str 继承,API 文档将能够知道这些值必须为 string 类型并且能够正确地展示出来。

然后创建具有固定值的类属性,比如 yinyu s1s2

from enum import Enum

class ModelName(str, Enum):
    yinyu = "yinyu_v"
    s1 = "s1_v"
    s2 = "s2_v"

枚举(或 enums)从 3.4 版本起在 Python 中可用。

② 声明路径参数

使用定义好的枚举类(ModelName)创建一个带有类型标注的路径参数:

'''包含枚举的路径参数'''
@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):

路径参数 model_name 的值将传递给函数 get_model 的参数 model_name,并且这个值的取值范围只能是 ModelName 枚举类中类属性的值。

③ 使用 Python 枚举类型

此时路径参数的值将是一个枚举成员,那么可以做如下的事情,包括比较枚举成员if ModelName is ModelName.yinyu)、获取枚举值(model_name.value)、返回枚举成员(ModelName.s2)等~

@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    # 第 1 种判断方式
    if ModelName is ModelName.yinyu:
        return {"model_name": model_name, "message": "yinyu get"}
    # 第 2 种判断方式,效果一样
    if model_name.value == "s1_name":
        return {"model_name": model_name, "message": "s1 get"}
    else:
        return {"model_name": ModelName.s2, "message": "s2 get"}

📌 请求该路径

完全代码:

from enum import Enum
from fastapi import FastAPI

app = FastAPI()

class ModelName(str, Enum):
    yinyu = "yinyu_v"
    s1 = "s1_v"
    s2 = "s2_v"

'''包含枚举的路径参数'''
@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    # 第 1 种判断方式
    if ModelName is ModelName.yinyu:
        return {"model_name": model_name, "message": "yinyu get"}
    # 第 2 种判断方式,效果一样
    if model_name.value == "s1_name":
        return {"model_name": model_name, "message": "s1 get"}
    else:
        return {"model_name": ModelName.s2, "message": "s2 get"}

访问 127.0.0.1:8000/models/yinyu_v,响应如下 👇,可以确定地是路径参数中的枚举类校验是以枚举成员的属性为准的,比如 yinyu 的属性值为 yinyu_v

1.5 包含路径的路径参数

适用于文件操作,假设现在你有一个路径操作:/files/{file_path},但是你需要 file_path 本身包含一个 路径, 比如 home/yinyu/myfile.txt

此时使用 Path 转换器就可以进行转换,你可以这样使用它:

@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
    return {"file_path": file_path}

参数的名称为 file_path,结尾部分的 :path 说明该参数应匹配任意的路径。

你可能会需要参数包含 /home/johndoe/myfile.txt,以斜杠(/)开头。此时,URL 将会是 /files//home/johndoe/myfile.txt,在files 和 home 之间有一个双斜杠(//)。

2 基础_查询参数

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

2.1 声明查询参数

简单声明两个查询参数,可以看到,他和路径参数是不一样的 👇

from fastapi import FastAPI

app = FastAPI()

@app.get("/items1/")
async def read_item(skip: int, limit: int):
    return {"skip": skip,"limit": limit}

查询字符串是键值对的集合,这些键值对位于 URL 之后,并以 & 符号分隔。

此时访问 http://127.0.0.1:8000/items/?skip=0&limit=10 👇,同时该查询参数也是必需的,因为这两个查询参数没有设置默认值None

其中:

  • skip:对应的值为 0
  • limit:对应的值为 10

由于它们是 URL 的一部分,因此它们的"原始值"是字符串。 但是为它们声明了 Python 类型(在上面的示例中为 int)时,它们将转换为该类型并针对该类型进行校验。

2.2 默认值

由于查询参数不是路径的固定部分,因此它们可以是可选的,并且可以有默认值。比如给上边接口中的查询参数分别设置默认值为 010

@app.get("/items2/")
async def read_item(skip: int = 0, limit: int = 10):
    return {"skip": skip,"limit": limit}

若此时访问 127.0.0.1:8000/items2/,虽然未设定查询参数,但是查询参数会成为事先设定好的默认值 👇

若此时访问 127.0.0.1:8000/items2/?skip=20,skip 将成为在 URL 中设定的值,而 limit 依旧是默认值 👇

2.3 可选参数

通过同样的方式,你可以将它们的默认值设置为 None 来声明可选查询参数:

from typing import Union 

@app.get("/items3/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

其中,查询参数 q 将是可选的,并且默认值为 NoneUnion 的作用是传递两种参数,q 既可以是 str,也可以为空。

若此时访问 127.0.0.1:8000/items3/yinyu,正常返回,说明查询参数 q 已经可选 👇

若此时访问 127.0.0.1:8000/items3/yinyu?q=,也是正常返回,可以简单理解为:q=None,这就是Union 的作用。

 若此时访问 127.0.0.1:8000/items3/yinyu?q=yinyu_v,正常返回 👇

2.4 类型转换

你还可以声明 bool 类型,它们将被自动转换:

@app.get("/items4/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

此时,访问 http://127.0.0.1:8000/items4/yinyu?short=1 ,其中 1 也可以是 True 、true、on、yes中其中一个,包括任何其他的变体形式(大写,首字母大写等等),你的函数接收的 short 参数都会是布尔值 True

对于值为 False 的情况也是一样的。

3 数值校验_查询参数

3.1 Query 使用

Query 是 FastAPI 专门用来装饰查询参数的类,简单使用如下 👇

from typing import Union
#首先从 fastapi 导入 Query
from fastapi import FastAPI,Query

app = FastAPI()

@app.get("/items1/") #然后使用 Query 修饰查询参数
async def read_items(q: Union[str, None] = Query(description="items1 interface")):
    query_items = {"q": q}
    return query_items

description 是 Query 中的一个字段,用来描述该参数;Union 的作用是传递两种参数,q 既可以是 str,也可以为空。

📌 文档

此时访问 http://127.0.0.1:8000/docs,可看到描述信息~

3.2 通过 Query 校验

除了上边的 description ,Query 还可以进行一些额外的校验

① default—默认值

@app.get("/items21/")
async def read_items(q: Union[str, None] = Query(default=None)):
    query_items = {"q": q}
    return query_items

此时,该查询参数等同于 :q: Union[str, None] = None

当然,你也可以将默认值设为有效值:

@app.get("/items22/")
async def read_items(q: str = Query(default="fixedquery")):
    query_items = {"q": q}
    return query_items

此时,该查询参数等同于 :q = "fixedquery"

② max_length/min_length—字符最大/小长度

@app.get("/items2/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50, min_length=3)):
    query_items = {"q": q}
    return query_items

max_length 用于限制查询参数的最大长度,min_length 用于限制查询参数的最小长度,若超出限制将会报错。

注意:max_length 和 min_length 仅可用于 str 类型的查询参数。

③ regex—正则表达式

@app.get("/items4/")
async def read_items(
    q: Union[str, None] = Query(default=None, regex="^fixedquery$")
):
    query_items = {"q": q}
    return query_items

这个指定的正则表达式通过以下规则检查接收到的参数值:

  • ^:以该符号之后的字符开头,符号之前没有字符。
  • fixedquery: 匹配 fixedquery。
  • $: 到此结束,在 fixedquery 之后不匹配任何字符。

也就是说该接口的查询参数只能是"fixedquery",不然就会报错,当然其他的正则表达式都是可以拿来用的!

④ 声明必需参数

首先当使用 Query ,同时需要声明一个值是必需的,只需不声明默认参数:

@app.get("/items5/")
async def read_items(q: str = Query(min_length=3)):
    query_items = {"q": q}
    return query_items

有另一种方法可以显式的声明一个值是必需的,即将该参数的默认值设为 ...

@app.get("/items6/")
async def read_items(q: str = Query(default=..., min_length=3)):
    query_items = {"q": q}
    return query_items

如果不想使用 ...,那么可以从 Pydantic 导入并使用 Required

from pydantic import Required

@app.get("/items7/")
async def read_items(q: str = Query(default=Required, min_length=3)):
    query_items = {"q": q}
    return query_items

总的来说,我认为直接省略 default 即可。

⑤ 声明更多元数据

你可以为查询参数声明额外的校验和元数据,比如:

  • alias:参数别名
  • title:参数标题
  • description:描述
  • deprecated:弃用
@app.get("/items8/")
async def read_items(
    q: Union[str, None] = Query(
        default=None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        alias="item-query", #别名
        deprecated=True
    )
):
    query_items = {"q": q}
    return query_items

大家不妨自己去试一下,然后访问 http://127.0.0.1:8000/docs 查看这些元数据在文档中的表现~

3.3 查询参数设定为列表/多个值

我们还可以使用 Query 去接收一组值。

① List[str]

一种方式是使用 List[str] 来接收一组值:

@app.get("/items9/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
    query_items = {"q": q}
    return query_items

此时,访问 localhost:8000/items9/?q=foo&q=bar 👇

这是因为参数 q 中以一个 Python list 的形式接收到查询参数 q 的多个值(foo bar)。

同样的,我们可以定义在没有任何给定值时的默认 list 值:

@app.get("/items10/")
async def read_items(q: List[str] = Query(default=["foo", "bar"])):
    query_items = {"q": q}
    return query_items

② list

你也可以直接使用 list 代替 List [str]

@app.get("/items11/")
async def read_items(q: list = Query(default=[])):
    query_items = {"q": q}
    return query_items

注意:在这种情况下 FastAPI 将不会检查列表的内容。

例如,List[int] 将检查(并记录到文档)列表的内容必须是整数,但是单独的 list 不会。

4 数值校验_路径参数

和前边使用 Query 声明查询参数的更多验证和元数据的方法相同,我们也可以通过Path声明路径参数的相同类型的验证和元数据。

4.1 Path 使用

简单来说,引入 Path,然后

#1.从 fastapi 导入 Path
from fastapi import FastAPI,Path

app = FastAPI()

@app.get("/items1/{item_id}")
async def read_items(
    #2.声明路径参数 item_id的 title 元数据值
    item_id: int = Path(title="The ID of the item to get"),
):
    return {"item_id": item_id}

路径参数总是必需的,你可以在声明时使用 ... 将其标记为必需参数。 不过,即使你不设置或使用 None 声明路径参数,那么也不会有任何影响,它依然会是必需参数。

4.2 按需对参数排序

如果你要声明 q 查询参数而不使用 Query 或任何默认值,并且使用 Path 声明路径参数 item_id 和使用不同的顺序,则 Python 对此有一些特殊的语法。语法规则如下:

  • 传递 * 作为函数的第一个参数。

Python 不会对该 * 做任何事情,但是它将知道之后的所有参数都应作为关键字参数(键值对),也被称为 kwargs,来调用。即使它们没有默认值。

@app.get("/items2/{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

此时访问 localhost:8000/items2/2222?q=yinyu 👇

若将 q 和 item_id 顺序调换一下,实际接口请求时也不会收到影响:

@app.get("/items2/{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

4.3 通过 Path 校验

使用 Query Path(以及后边其他的类)不仅可以声明字符串约束,还可以声明数值约束(intfloat 等数值类型)。

① ge—大于等于

比如,添加 ge=1 后,item_id 将必须是一个大于(greater than)或等于(equal1 的整数。

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

② gt—大于,le—小于等于

同样的规则适用于:

  • gt:大于(greater than)
  • le:小于等于(less than or equal)
@app.get("/items4/{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

③ 总结

  • gt:大于(greater than)
  • ge:大于等于(greater than or equal)
  • lt:小于(less than)
  • le:小于等于(less than or equal)

Query、Path 以及你后面会看到的其他类继承自一个共同的 Param 类(不需要直接使用它)。 而且它们都共享相同的所有你已看到并用于添加额外校验和元数据的参数。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHPMySQL基础(一):创建数据库并通过PHP进行连接

PHP同样可以对数据库进行连接,并且实现增删改查、登录注册等功能,这一篇写一下怎么使用PHP去连接MySQL数据库 目录 一、创建数据库 1.1 登录页面 1.2 创建数据库 1.3 创建数据库表 1.4 添加表字段 1.5 插入数据 1.6 导出和导入 二、PHP连接数据…

华为OD机试真题B卷 Java 实现【报文重排序】,附详细解题思路

一、题目描述 对报文进行重传和重排序是常用的可靠性机制&#xff0c;重传缓冲区内有一定数量的子报文&#xff0c;每个子报文在原始报文中的顺序已知&#xff0c;现在需要恢复出原始报文。 二、输入描述 输入第一行为N&#xff0c;表示子报文的个数&#xff0c;0 < N &l…

SpringBoot 配置文件和日志文件

目录 一、SpringBoot配置文件 配置文件的格式 .properties配置文件格式 .yml配置文件格式 .properties 与 .yml的区别 配置文件的读取 .properties 与 .yml的区别 设置不同环境的配置⽂件 二、SpringBoot日志文件 日志打印的步骤 得到日志对象 方法一&#xff1a;使…

vulnhub靶场之RAGNAR LOTHBROK: 1

1.信息收集 探测存活主机&#xff0c;输入&#xff1a;netdiscover -r 192.168.239.0/24 &#xff0c;发现192.168.239.178存活。 对目标主机192.168.239.178进行端口扫描&#xff0c;发现存活21(ftp)、80、443、3306端口。 浏览器访问http://192.168.239.178&#xff0c;发…

设计模式 - 代理模式

基本介绍: 代理模式&#xff1a;为一个对象提供一个替身&#xff0c;以控制对这个对象的访问。即通过代理 对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的 功能操作,即扩展目标对象的功能。被代理的对象可以是远程对象、创建开销大的对象或需要安全控…

chatgpt赋能python:Python三次方根的用途和计算方法

Python三次方根的用途和计算方法 如果您是一位Python编程工程师&#xff0c;您可能会经常需要用到Python的数学计算功能。在这篇文章中&#xff0c;我们将探讨Python三次方根的概念和使用&#xff0c;以及如何在Python中计算三次方根。 什么是三次方根&#xff1f; 三次方根…

SpringBoot 框架

SpringBoot 框架 SpringBoot 简介SpringBoot 开发步骤SpringBoot工程快速启动SpringBoot概述起步依赖自动装配切换web服务器 配置文件配置文件格式yaml格式yaml配置文件数据读取Value注解读取配置文件Environment对象自定义对象多环境配置 SpringBoot 整合 SpringBoot 简介 Sp…

这个 计数排序详解过程 我能吹一辈子!!!

文章目录 计数排序概念计数排序算法思路计数排序算法过程计数排序代码实现计数排序缺陷 计数排序概念 计数排序是一个非基于比较的排序算法&#xff0c;元素从未排序状态变为已排序状态的过程&#xff0c;是由额外空间的辅助和元素本身的值决定的。该算法于1954年由 Harold H.…

流行框架(一)EventBus(组件通信)、ARouter(页面跳转)

文章目录 EventBus基本使用EventBus三要素五种线程模式使用步骤EventBus黏性事件&#xff08;sticky event&#xff09; 工作原理中介者模式源码解读Event Bus中介者对象register() / 注册发布事件 / post Arouter组件化开发组件化开发的优点组件分层方案组件化的gradle工程 AR…

C919商业首航 背后功臣风洞实验室有多牛

5月28日&#xff0c;国产大型客机C919&#xff0c;顺利完成商业首航。 首航背后意味着该机型从研发、制造、取证到投运全面贯通&#xff0c;广大旅客终于有机会坐国产大飞机出行了。 很多人不知道C919其实是依托我国独立自主设计制造的世界级风洞群和风洞实验室反复测试“百炼…

Linux部署jumpserver堡垒机及问题汇总

部署过程相对复杂&#xff01;请耐心浏览&#xff01; 目录 一、jumpserver堡垒机简介 1.1 为什么需要使用堡垒机? 1.2 堡垒机主要功能 二、准备工作 2.1 关闭防火墙以及SElinux 1.2 时间同步 1.3 更改主机名 1.4 yum源备份及准备 1.5 安装初始工具 1.6 修改系统字…

基于PS-InSAR技术的形变监测分析流程

基于PS-InSAR技术的形变监测分析流程 文章目录 基于PS-InSAR技术的形变监测分析流程1. 背景知识1.1 PS-InSAR技术1.1.1 雷达干涉测量1.1.2 InSAR技术1.1.3 技术原理1.1.4 技术特征1.1.5 技术优化1.1.6 应用 1.2 Sentinel-1数据1.2.1 Sentinel-1简介1.2.2 Sentinel-1扫描模式1.2…

一分钟学会怎么让chatGPT帮你写python代码(含使用地址)

一分钟学会怎么让chatGPT帮你写python代码&#xff08;含使用地址&#xff09; 我们用chatGPT做一个python的计算器脚本为例 提出需求 1、给定角色定位 2、提出要求 3、提出要求的细节 标题等待片刻&#xff0c;等待chatGPT生成脚本即可 import tkinter as tkclass Calc…

去公司面试,10:00刚进去,10:08就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内…

33 KVM管理设备-配置虚拟机PCIe控制器

文章目录 33 KVM管理设备-配置虚拟机PCIe控制器33.1 概述33.2 配置PCIe Root、PCIe Root Port和PCIe-PCI-Bridge33.2.1 简化配置方法33.2.1完整配制方法 33 KVM管理设备-配置虚拟机PCIe控制器 33.1 概述 虚拟机内部的网卡、磁盘控制器、PCIe直通设备都需要挂接到PCIe Root Po…

IOC源码解析

目录 主要从3方面进行解析 Bean与BeanDefinition 容器初始化主要做的事情(主要脉络) BeanFactory ApplicationContext 模板方法模式 Resource、ResourceLoader、容器之间的关系 BeanDefinitionReader BeanDefinition的注册 小结 主要从3方面进行解析 解析配置定位与注…

EMNLP -- Call for Main Conference Papers

以下内容链接&#xff1a;Call for Main Conference Papers - EMNLP 2023 目录 审核流程&#xff1a; 与 ARR 的交叉提交政策 注意&#xff1a; 注意&#xff1a; 重要日期 强制性摘要提交 提交方向 论文提交信息 论文提交和模板 确认 长论文 短文 贡献 演示模式 著作权 引用与…

Vue设计记事本

项目描述 项目实现功能有&#xff1a;记录今天要完成的任务&#xff0c;勾选已经完成的任务&#xff0c;删除已经完成的全部任务。 界面展示&#xff1a; 代码展示 创建一个Myitem.vue文件夹 <template><li><label ><input type"checkbox"…

机器学习 监督学习 Week2

Lib01 多变量线性回归 依旧是房价预测&#xff0c;但这次引入了多个变量&#xff0c;不仅仅只有房屋面积影响着房价&#xff0c;依旧尝试使用梯度下降算法找到最优的【w,b】&#xff0c;并且习惯使用向量点乘运算提高效率 import copy, math import numpy as np import matplot…

微内核和大内核

微内核和大内核是操作系统内核的两种不同设计思路。 图片来源 微内核 微内核是指将操作系统内核中的核心功能&#xff08;如进程管理、内存管理、设备驱动等&#xff09;作为独立进程运行&#xff0c;各进程间通过IPC(进程间通信)进行通讯。其中微内核相当于一个消息中转站&…