三周精通FastAPI:28 构建更大的应用 - 多个文件

官方文档:https://fastapi.tiangolo.com/zh/tutorial/bigger-applications

更大的应用 - 多个文件¶

如果你正在开发一个应用程序或 Web API,很少会将所有的内容都放在一个文件中。

FastAPI 提供了一个方便的工具,可以在保持所有灵活性的同时构建你的应用程序。

Info

如果你来自 Flask,那这将相当于 Flask 的 Blueprints。

一个文件结构示例¶

假设你的文件结构如下:

.
├── app
│   ├── __init__.py
│   ├── main.py
│   ├── dependencies.py
│   └── routers
│   │   ├── __init__.py
│   │   ├── items.py
│   │   └── users.py
│   └── internal
│       ├── __init__.py
│       └── admin.py

Tip

上面有几个 __init__.py 文件:每个目录或子目录中都有一个。

这就是能将代码从一个文件导入到另一个文件的原因。

例如,在 app/main.py 中,你可以有如下一行:

from app.routers import items
  • app 目录包含了所有内容。并且它有一个空文件 app/__init__.py,因此它是一个「Python 包」(「Python 模块」的集合):app
  • 它包含一个 app/main.py 文件。由于它位于一个 Python 包(一个包含 __init__.py 文件的目录)中,因此它是该包的一个「模块」:app.main
  • 还有一个 app/dependencies.py 文件,就像 app/main.py 一样,它是一个「模块」:app.dependencies
  • 有一个子目录 app/routers/ 包含另一个 __init__.py 文件,因此它是一个「Python 子包」:app.routers
  • 文件 app/routers/items.py 位于 app/routers/ 包中,因此它是一个子模块:app.routers.items
  • 同样适用于 app/routers/users.py,它是另一个子模块:app.routers.users
  • 还有一个子目录 app/internal/ 包含另一个 __init__.py 文件,因此它是又一个「Python 子包」:app.internal
  • app/internal/admin.py 是另一个子模块:app.internal.admin

带有注释的同一文件结构:

.
├── app                  # 「app」是一个 Python 包
│   ├── __init__.py      # 这个文件使「app」成为一个 Python 包
│   ├── main.py          # 「main」模块,例如 import app.main
│   ├── dependencies.py  # 「dependencies」模块,例如 import app.dependencies
│   └── routers          # 「routers」是一个「Python 子包」
│   │   ├── __init__.py  # 使「routers」成为一个「Python 子包」
│   │   ├── items.py     # 「items」子模块,例如 import app.routers.items
│   │   └── users.py     # 「users」子模块,例如 import app.routers.users
│   └── internal         # 「internal」是一个「Python 子包」
│       ├── __init__.py  # 使「internal」成为一个「Python 子包」
│       └── admin.py     # 「admin」子模块,例如 import app.internal.admin

APIRouter

假设专门用于处理用户逻辑的文件是位于 /app/routers/users.py 的子模块。

你希望将与用户相关的路径操作与其他代码分开,以使其井井有条。

但它仍然是同一 FastAPI 应用程序/web API 的一部分(它是同一「Python 包」的一部分)。

你可以使用 APIRouter 为该模块创建路径操作

导入 APIRouter

你可以导入它并通过与 FastAPI 类相同的方式创建一个「实例」:

app/routers/users.py

 
from fastapi import APIRouterrouter = APIRouter()

使用 APIRouter 的路径操作

然后你可以使用它来声明路径操作

使用方式与 FastAPI 类相同:

app/routers/users.py

 
@router.get("/users/", tags=["users"])
async def read_users():return [{"username": "Rick"}, {"username": "Morty"}]@router.get("/users/me", tags=["users"])
async def read_user_me():return {"username": "fakecurrentuser"}@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):return {"username": username}

你可以将 APIRouter 视为一个「迷你 FastAPI」类。

所有相同的选项都得到支持。

所有相同的 parametersresponsesdependenciestags 等等。

Tip

在此示例中,该变量被命名为 router,但你可以根据你的想法自由命名。

我们将在主 FastAPI 应用中包含该 APIRouter,但首先,让我们来看看依赖项和另一个 APIRouter

依赖项¶

我们了解到我们将需要一些在应用程序的好几个地方所使用的依赖项。

因此,我们将它们放在它们自己的 dependencies 模块(app/dependencies.py)中。

现在我们将使用一个简单的依赖项来读取一个自定义的 X-Token 请求首部:

app/dependencies.py

 
from fastapi import Header, HTTPExceptionasync def get_token_header(x_token: str = Header()):if x_token != "fake-super-secret-token":raise HTTPException(status_code=400, detail="X-Token header invalid")async def get_query_token(token: str):if token != "jessica":raise HTTPException(status_code=400, detail="No Jessica token provided")

Tip

我们正在使用虚构的请求首部来简化此示例。

但在实际情况下,使用集成的安全性实用工具会得到更好的效果。

其他使用 APIRouter 的模块¶

假设你在位于 app/routers/items.py 的模块中还有专门用于处理应用程序中「项目」的端点。

你具有以下路径操作

  • /items/
  • /items/{item_id}

这和 app/routers/users.py 的结构完全相同。

但是我们想变得更聪明并简化一些代码。

我们知道此模块中的所有路径操作都有相同的:

  • 路径 prefix/items
  • tags:(仅有一个 items 标签)。
  • 额外的 responses
  • dependencies:它们都需要我们创建的 X-Token 依赖项。

因此,我们可以将其添加到 APIRouter 中,而不是将其添加到每个路径操作中。

app/routers/items.py

 
from fastapi import APIRouter, Depends, HTTPExceptionfrom ..dependencies import get_token_headerrouter = APIRouter(prefix="/items",tags=["items"],dependencies=[Depends(get_token_header)],responses={404: {"description": "Not found"}},
)fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}@router.get("/")
async def read_items():return fake_items_db@router.get("/{item_id}")
async def read_item(item_id: str):if item_id not in fake_items_db:raise HTTPException(status_code=404, detail="Item not found")return {"name": fake_items_db[item_id]["name"], "item_id": item_id}@router.put("/{item_id}",tags=["custom"],responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):if item_id != "plumbus":raise HTTPException(status_code=403, detail="You can only update the item: plumbus")return {"item_id": item_id, "name": "The great Plumbus"}

由于每个路径操作的路径都必须以 / 开头,例如:

@router.get("/{item_id}")
async def read_item(item_id: str):...

...前缀不能以 / 作为结尾。

因此,本例中的前缀为 /items

我们还可以添加一个 tags 列表和额外的 responses 列表,这些参数将应用于此路由器中包含的所有路径操作

我们可以添加一个 dependencies 列表,这些依赖项将被添加到路由器中的所有路径操作中,并将针对向它们发起的每个请求执行/解决。

Tip

请注意,和路径操作装饰器中的依赖项很类似,没有值会被传递给你的路径操作函数

最终结果是项目相关的路径现在为:

  • /items/
  • /items/{item_id}

...如我们所愿。

  • 它们将被标记为仅包含单个字符串 "items" 的标签列表。
    • 这些「标签」对于自动化交互式文档系统(使用 OpenAPI)特别有用。
  • 所有的路径操作都将包含预定义的 responses
  • 所有的这些路径操作都将在自身之前计算/执行 dependencies 列表。
    • 如果你还在一个具体的路径操作中声明了依赖项,它们也会被执行
    • 路由器的依赖项最先执行,然后是装饰器中的 dependencies,再然后是普通的参数依赖项。
    • 你还可以添加具有 scopes 的 Security 依赖项。

Tip

在 APIRouter中具有 dependencies 可以用来,例如,对一整组的路径操作要求身份认证。即使这些依赖项并没有分别添加到每个路径操作中。

Check

prefixtagsresponses 以及 dependencies 参数只是(和其他很多情况一样)FastAPI 的一个用于帮助你避免代码重复的功能。

导入依赖项¶

这些代码位于 app.routers.items 模块,app/routers/items.py 文件中。

我们需要从 app.dependencies 模块即 app/dependencies.py 文件中获取依赖函数。

因此,我们通过 .. 对依赖项使用了相对导入:

app/routers/items.py

 
from fastapi import APIRouter, Depends, HTTPExceptionfrom ..dependencies import get_token_header

相对导入如何工作¶

Tip

如果你完全了解导入的工作原理,请从下面的下一部分继续。

一个单点 .,例如:

from .dependencies import get_token_header 

表示:

  • 从该模块(app/routers/items.py 文件)所在的同一个包(app/routers/ 目录)开始...
  • 找到 dependencies 模块(一个位于 app/routers/dependencies.py 的虚构文件)...
  • 然后从中导入函数 get_token_header

但是该文件并不存在,我们的依赖项位于 app/dependencies.py 文件中。

请记住我们的程序/文件结构是怎样的:


两个点 ..,例如:

from ..dependencies import get_token_header 

表示:

  • 从该模块(app/routers/items.py 文件)所在的同一个包(app/routers/ 目录)开始...
  • 跳转到其父包(app/ 目录)...
  • 在该父包中,找到 dependencies 模块(位于 app/dependencies.py 的文件)...
  • 然后从中导入函数 get_token_header

正常工作了!🎉


同样,如果我们使用了三个点 ...,例如:

from ...dependencies import get_token_header 

那将意味着:

  • 从该模块(app/routers/items.py 文件)所在的同一个包(app/routers/ 目录)开始...
  • 跳转到其父包(app/ 目录)...
  • 然后跳转到该包的父包(该父包并不存在,app 已经是最顶层的包 😱)...
  • 在该父包中,找到 dependencies 模块(位于 app/ 更上一级目录中的 dependencies.py文件)...
  • 然后从中导入函数 get_token_header

这将引用 app/ 的往上一级,带有其自己的 __init __.py 等文件的某个包。但是我们并没有这个包。因此,这将在我们的示例中引发错误。🚨

但是现在你知道了它的工作原理,因此无论它们多么复杂,你都可以在自己的应用程序中使用相对导入。🤓

添加一些自定义的 tagsresponses 和 dependencies

我们不打算在每个路径操作中添加前缀 /items 或 tags =["items"],因为我们将它们添加到了 APIRouter 中。

但是我们仍然可以添加更多将会应用于特定的路径操作的 tags,以及一些特定于该路径操作的额外 responses

app/routers/items.py

 
@router.put("/{item_id}",tags=["custom"],responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):if item_id != "plumbus":raise HTTPException(status_code=403, detail="You can only update the item: plumbus")return {"item_id": item_id, "name": "The great Plumbus"}

Tip

最后的这个路径操作将包含标签的组合:["items","custom"]

并且在文档中也会有两个响应,一个用于 404,一个用于 403

FastAPI 主体¶

现在,让我们来看看位于 app/main.py 的模块。

在这里你导入并使用 FastAPI 类。

这将是你的应用程序中将所有内容联结在一起的主文件。

并且由于你的大部分逻辑现在都存在于其自己的特定模块中,因此主文件的内容将非常简单。

导入 FastAPI

你可以像平常一样导入并创建一个 FastAPI 类。

我们甚至可以声明全局依赖项,它会和每个 APIRouter 的依赖项组合在一起:

app/main.py

 
from fastapi import Depends, FastAPIfrom .dependencies import get_query_token, get_token_headerapp = FastAPI(dependencies=[Depends(get_query_token)])

导入 APIRouter

现在,我们导入具有 APIRouter 的其他子模块:

app/main.py

 
from .routers import items, users

由于文件 app/routers/users.py 和 app/routers/items.py 是同一 Python 包 app 一个部分的子模块,因此我们可以使用单个点 . 通过「相对导入」来导入它们。

导入是如何工作的¶

这段代码:

from .routers import items, users 

表示:

  • 从该模块(app/main.py 文件)所在的同一个包(app/ 目录)开始...
  • 寻找 routers 子包(位于 app/routers/ 的目录)...
  • 从该包中,导入子模块 items (位于 app/routers/items.py 的文件) 以及 users (位于 app/routers/users.py 的文件)...

items 模块将具有一个 router 变量(items.router)。这与我们在 app/routers/items.py文件中创建的变量相同,它是一个 APIRouter 对象。

然后我们对 users 模块进行相同的操作。

我们也可以像这样导入它们:

from app.routers import items, users 

Info

第一个版本是「相对导入」:

from .routers import items, users 

第二个版本是「绝对导入」:

from app.routers import items, users 

要了解有关 Python 包和模块的更多信息,请查阅关于 Modules 的 Python 官方文档。

避免名称冲突¶

我们将直接导入 items 子模块,而不是仅导入其 router 变量。

这是因为我们在 users 子模块中也有另一个名为 router 的变量。如果我们一个接一个地导入,例如:

from .routers.items import router
from .routers.users import router

来自 users 的 router 将覆盖来自 items 中的 router,我们将无法同时使用它们。

因此,为了能够在同一个文件中使用它们,我们直接导入子模块:

app/main.py

 
from .routers import items, users

包含 users 和 items 的 APIRouter

现在,让我们来包含来自 users 和 items 子模块的 router

app/main.py

 
app.include_router(users.router)
app.include_router(items.router)
app.include_router(admin.router,prefix="/admin",tags=["admin"],dependencies=[Depends(get_token_header)],responses={418: {"description": "I'm a teapot"}},
)

Info

users.router 包含了 app/routers/users.py 文件中的 APIRouter

items.router 包含了 app/routers/items.py 文件中的 APIRouter

使用 app.include_router(),我们可以将每个 APIRouter 添加到主 FastAPI 应用程序中。

它将包含来自该路由器的所有路由作为其一部分。

"技术细节"

实际上,它将在内部为声明在 APIRouter 中的每个路径操作创建一个路径操作

所以,在幕后,它实际上会像所有的东西都是同一个应用程序一样工作。

Check

包含路由器时,你不必担心性能问题。

这将花费几微秒时间,并且只会在启动时发生。

因此,它不会影响性能。⚡

包含一个有自定义 prefixtagsresponses 和 dependencies 的 APIRouter

现在,假设你的组织为你提供了 app/internal/admin.py 文件。

它包含一个带有一些由你的组织在多个项目之间共享的管理员路径操作的 APIRouter

对于此示例,它将非常简单。但是假设由于它是与组织中的其他项目所共享的,因此我们无法对其进行修改,以及直接在 APIRouter 中添加 prefixdependenciestags 等:

app/internal/admin.py

 
from fastapi import APIRouterrouter = APIRouter()@router.post("/")
async def update_admin():return {"message": "Admin getting schwifty"}

但是我们仍然希望在包含 APIRouter 时设置一个自定义的 prefix,以便其所有路径操作以 /admin 开头,我们希望使用本项目已经有的 dependencies 保护它,并且我们希望它包含自定义的 tags 和 responses

我们可以通过将这些参数传递给 app.include_router() 来完成所有的声明,而不必修改原始的 APIRouter

app/main.py

 
app.include_router(users.router)
app.include_router(items.router)
app.include_router(admin.router,prefix="/admin",tags=["admin"],dependencies=[Depends(get_token_header)],responses={418: {"description": "I'm a teapot"}},
)

这样,原始的 APIRouter 将保持不变,因此我们仍然可以与组织中的其他项目共享相同的 app/internal/admin.py 文件。

结果是在我们的应用程序中,来自 admin 模块的每个路径操作都将具有:

  • /admin 前缀 。
  • admin 标签。
  • get_token_header 依赖项。
  • 418 响应。 🍵

但这只会影响我们应用中的 APIRouter,而不会影响使用它的任何其他代码。

因此,举例来说,其他项目能够以不同的身份认证方法使用相同的 APIRouter

包含一个路径操作

我们还可以直接将路径操作添加到 FastAPI 应用中。

这里我们这样做了...只是为了表明我们可以做到🤷:

app/main.py

 
@app.get("/")
async def root():return {"message": "Hello Bigger Applications!"}

它将与通过 app.include_router() 添加的所有其他路径操作一起正常运行。

"特别的技术细节"

注意:这是一个非常技术性的细节,你也许可以直接跳过

APIRouter 没有被「挂载」,它们与应用程序的其余部分没有隔离。

这是因为我们想要在 OpenAPI 模式和用户界面中包含它们的路径操作

由于我们不能仅仅隔离它们并独立于其余部分来「挂载」它们,因此路径操作是被「克隆的」(重新创建),而不是直接包含。


查看自动化的 API 文档¶

现在,使用 app.main 模块和 app 变量运行 uvicorn

uvicorn app.main:app --reload

然后打开位于 http://127.0.0.1:8000/docs 的文档。

你将看到使用了正确路径(和前缀)和正确标签的自动化 API 文档,包括了来自所有子模块的路径:

多次使用不同的 prefix 包含同一个路由器¶

你也可以在同一路由器上使用不同的前缀来多次使用 .include_router()

在有些场景这可能有用,例如以不同的前缀公开同一个的 API,比方说 /api/v1 和 /api/latest

这是一个你可能并不真正需要的高级用法,但万一你有需要了就能够用上。

在另一个 APIRouter 中包含一个 APIRouter

与在 FastAPI 应用程序中包含 APIRouter 的方式相同,你也可以在另一个 APIRouter 中包含 APIRouter,通过:

router.include_router(other_router) 

请确保在你将 router 包含到 FastAPI 应用程序之前进行此操作,以便 other_router 中的路径操作也能被包含进来。

实践

源代码

创建app目录,然后在目录里按照如下目录结构创建文件。

.
├── app
│   ├── __init__.py
│   ├── main.py
│   ├── dependencies.py
│   └── routers
│   │   ├── __init__.py
│   │   ├── items.py
│   │   └── users.py
│   └── internal
│       ├── __init__.py
│       └── admin.py

users.py文件

from fastapi import APIRouterrouter = APIRouter()@router.get("/users/", tags=["users"])
async def read_users():return [{"username": "Rick"}, {"username": "Morty"}]@router.get("/users/me", tags=["users"])
async def read_user_me():return {"username": "fakecurrentuser"}@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):return {"username": username}

dependentics.py文件

from typing import Annotatedfrom fastapi import Header, HTTPExceptionasync def get_token_header(x_token: Annotated[str, Header()]):if x_token != "fake-super-secret-token":raise HTTPException(status_code=400, detail="X-Token header invalid")async def get_query_token(token: str):if token != "jessica":raise HTTPException(status_code=400, detail="No Jessica token provided")

items.py文件

from fastapi import APIRouter, Depends, HTTPExceptionfrom ..dependencies import get_token_headerrouter = APIRouter(prefix="/items",tags=["items"],dependencies=[Depends(get_token_header)],responses={404: {"description": "Not found"}},
)fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}@router.get("/")
async def read_items():return fake_items_db@router.get("/{item_id}")
async def read_item(item_id: str):if item_id not in fake_items_db:raise HTTPException(status_code=404, detail="Item not found")return {"name": fake_items_db[item_id]["name"], "item_id": item_id}@router.put("/{item_id}",tags=["custom"],responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):if item_id != "plumbus":raise HTTPException(status_code=403, detail="You can only update the item: plumbus")return {"item_id": item_id, "name": "The great Plumbus"}

main.py文件

from fastapi import Depends, FastAPIfrom .dependencies import get_query_token, get_token_header
from .internal import admin
from .routers import items, usersapp = FastAPI(dependencies=[Depends(get_query_token)])app.include_router(users.router)
app.include_router(items.router)
app.include_router(admin.router,prefix="/admin",tags=["admin"],dependencies=[Depends(get_token_header)],responses={418: {"description": "I'm a teapot"}},
)@app.get("/")
async def root():return {"message": "Hello Bigger Applications!"}

admin.py文件

from fastapi import APIRouterrouter = APIRouter()@router.post("/")
async def update_admin():return {"message": "Admin getting schwifty"}

启动服务

uvicorn app.main:app --reload

测试

查看文档

首先打开文档页面:http://127.0.0.1:8000/docs

可以看到web路径:

使用token登录

curl -X 'GET' \'http://127.0.0.1:8000/users/me?token=jessica' \-H 'accept: application/json'

 输出:

{"username":"fakecurrentuser"}

使用其它用户和token登录

curl -X 'GET' \'http://127.0.0.1:8000/users/hello?token=jessica' \-H 'accept: application/json'

返回:{"username":"hello"}

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

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

相关文章

【react使用AES对称加密的实现】

react使用AES对称加密的实现 前言使用CryptoJS库密钥存放加密方法解密方法结语 前言 项目中要求敏感信息怕被抓包泄密必须进行加密传输处理,普通的md5加密虽然能解决传输问题,但是项目中有权限的用户是需要查看数据进行查询的,所以就不能直接…

【STM32】INA3221三通道电压电流采集模块,HAL库

一、简单介绍 芯片的datasheet地址: INA3221 三通道、高侧测量、分流和总线电压监视器,具有兼容 I2C 和 SMBUS 的接口 datasheet (Rev. B) 笔者所使用的INA3221是淘宝买的模块 原理图 模块的三个通道的电压都是一样,都是POWER。这个芯片采用…

《机器人SLAM导航核心技术与实战》第1季:第10章_其他SLAM系统

视频讲解 【第1季】10.第10章_其他SLAM系统-视频讲解 【第1季】10.1.第10章_其他SLAM系统_RTABMAP算法-视频讲解 【第1季】10.2.第10章_其他SLAM系统_VINS算法-视频讲解 【第1季】10.3.第10章_其他SLAM系统_机器学习与SLAM-视频讲解 第1季:第10章_其他SLAM系统 …

《HelloGitHub》第 103 期

兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…

【OJ题解】C++实现反转字符串中的每个单词

💵个人主页: 起名字真南 💵个人专栏:【数据结构初阶】 【C语言】 【C】 【OJ题解】 题目要求:给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。 题目链接: 反转字符串中的所…

Oracle OCP认证考试考点详解082系列09

题记: 本系列主要讲解Oracle OCP认证考试考点(题目),适用于19C/21C,跟着学OCP考试必过。 41. 第41题: 题目 41.Examine the description of the EMPLOYEES table NLS_DATE_FORMAT is set to DD-MON-YY Which query…

创建线程时传递参数给线程

在C中,可以使用 std::thread 来创建和管理线程,同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…

Linux下cgdb/gdb调试以及关于操作系统那些事

目录 一.gdb调试 1.1debug和release版本有什么区别? 1.2性能优化 1.3gdb的使用 1.4cgdb的安装 二.什么是硬件 三.冯诺依曼体系 四.操作系统(OS) 4.1理解操作系统 4.1.1操作系统是什么? 4.1.2为什么要有操作系统? 4.1.3 OS-银行 4.1.4OS如何管理 理解库文件和系…

Kafka相关知识点(上)

为什么要使用消息队列? 使用消息队列的主要目的主要记住这几个关键词:解耦、异步、削峰填谷。 解耦: 在一个复杂的系统中,不同的模块或服务之间可能需要相互依赖,如果直接使用函数调用或者 API 调用的方式,会造成模块之间的耦合…

ureport配置方法

1、项目启动后登录这个网址,ip和端口自己系统的 http://localhost:8080/ureport/designer 点击这个地方,图标类似一个文件夹选择下图标注的两个文件,这两个文件就是eoa系统要用到的报表文件,还是点击类似文件夹图标的图标 正在上…

Java学习路线:JUnit单元测试

目录 使用JUnit 导入依赖 使用Junit 添加前置/后置操作 当项目十分庞大时,如果想测试一个很小的功能,都要启动整个项目来测试,会很浪费时间。 那能否将某个小功能单独拆出来进行测试呢? 这就是单元测试的作用。而JUnit就是一…

RK3568平台(camera篇)车载摄像头串行器和解串器方案

一.串行器和解串器简介 SerDes是Serializer/Deserializer的缩写,即串行器和解串器。由于同轴线的传输延迟几乎可以忽略不计(ns级别),相当于将原来只能短距离传输的高速并行信号(MIPI/I2C/CLK等)的传输距离延长,真正做到高带宽、低延迟、长距离的数据传输。 串行器(Seri…

【A】【Maven项目热部署】将Maven项目热部署到远程tomcat服务器上

将Maven项目热部署到远程tomcat中 文章目录 将Maven项目热部署到远程tomcat中1.解决方案:2.实现3.Tomcat中的Root项目的配置和使用4.在tomcat-user.xml中配置远程服务器tomcat的账户信息5.修改 IP 访问权限6.登录ROOT项目,使用Manager App功能管理tomcat…

Scrum价值观

五大价值观 尊重,勇气,专注,承诺,开放 三大支柱(经验主义的三大支柱) 透明度,检查,适应 三大职责(不是三大角色) 产品负责人,开发人员&#xff0c…

【机器学习】26. 聚类评估方法

聚类评估方法 1. Unsupervised Measure1.1. Method 1: measure cohesion and separationSilhouette coefficient Method 2:Correlation between two similarity matricesMethod 3:Visual Inspection of similarity matrix 2. Supervised measures3. 决定…

线性代数求特征值和特征向量的技巧

考场时间很重要,所以学会方法计算挺重要。 一、求特征值: 大部分题目我们都可以通过矩阵行变化将矩阵的某一行的元素化简成只剩一个值,再按一行展开。这是我们首先应该想的。 但是考场难免会紧张,导致一时半会无法看出&#xf…

Java内存区域

前言 对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像 C/C程序开发程序员这样为每一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机&#xf…

“七巨头”(The Magnificent 7)科技公司财报喜忧参半看AI

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

图片分割--UNet

1.网络结构 结构可以分为两部分 左边部分是编码结构,进行特征提取 右边是解码结果,进行特征还原 2.数据集准备 import os.path from torchvision import transforms from torch.utils.data import Dataset from utils import *#数据归一化 transform transforms.Compose([tr…

【论文速读】| RED QUEEN: 保护大语言模型免受隐蔽多轮越狱攻击

基本信息 原文标题:RED QUEEN: Safeguarding Large Language Models against Concealed Multi-Turn Jailbreaking 原文作者:Yifan Jiang, Kriti Aggarwal, Tanmay Laud, Kashif Munir, Jay Pujara, Subhabrata Mukherjee 作者单位:Hippocr…