mirror of https://github.com/tiangolo/fastapi.git
🌐 Add Chinese translation for `docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md` (#4971)
Co-authored-by: Jeodre <jedore_fight@189.cn> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
parent
6aa9ef0c96
commit
fcab59be88
|
|
@ -0,0 +1,247 @@
|
|||
# 类作为依赖项
|
||||
|
||||
在深入探究 **依赖注入** 系统之前,让我们升级之前的例子。
|
||||
|
||||
## 来自前一个例子的`dict`
|
||||
|
||||
在前面的例子中, 我们从依赖项 ("可依赖对象") 中返回了一个 `dict`:
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及以上"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
但是后面我们在路径操作函数的参数 `commons` 中得到了一个 `dict`。
|
||||
|
||||
我们知道编辑器不能为 `dict` 提供很多支持(比如补全),因为编辑器不知道 `dict` 的键和值类型。
|
||||
|
||||
对此,我们可以做的更好...
|
||||
|
||||
## 什么构成了依赖项?
|
||||
|
||||
到目前为止,您看到的依赖项都被声明为函数。
|
||||
|
||||
但这并不是声明依赖项的唯一方法(尽管它可能是更常见的方法)。
|
||||
|
||||
关键因素是依赖项应该是 "可调用对象"。
|
||||
|
||||
Python 中的 "**可调用对象**" 是指任何 Python 可以像函数一样 "调用" 的对象。
|
||||
|
||||
所以,如果你有一个对象 `something` (可能*不是*一个函数),你可以 "调用" 它(执行它),就像:
|
||||
|
||||
```Python
|
||||
something()
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```Python
|
||||
something(some_argument, some_keyword_argument="foo")
|
||||
```
|
||||
|
||||
这就是 "可调用对象"。
|
||||
|
||||
## 类作为依赖项
|
||||
|
||||
您可能会注意到,要创建一个 Python 类的实例,您可以使用相同的语法。
|
||||
|
||||
举个例子:
|
||||
|
||||
```Python
|
||||
class Cat:
|
||||
def __init__(self, name: str):
|
||||
self.name = name
|
||||
|
||||
|
||||
fluffy = Cat(name="Mr Fluffy")
|
||||
```
|
||||
|
||||
在这个例子中, `fluffy` 是一个 `Cat` 类的实例。
|
||||
|
||||
为了创建 `fluffy`,你调用了 `Cat` 。
|
||||
|
||||
所以,Python 类也是 **可调用对象**。
|
||||
|
||||
因此,在 **FastAPI** 中,你可以使用一个 Python 类作为一个依赖项。
|
||||
|
||||
实际上 FastAPI 检查的是它是一个 "可调用对象"(函数,类或其他任何类型)以及定义的参数。
|
||||
|
||||
如果您在 **FastAPI** 中传递一个 "可调用对象" 作为依赖项,它将分析该 "可调用对象" 的参数,并以处理路径操作函数的参数的方式来处理它们。包括子依赖项。
|
||||
|
||||
这也适用于完全没有参数的可调用对象。这与不带参数的路径操作函数一样。
|
||||
|
||||
所以,我们可以将上面的依赖项 "可依赖对象" `common_parameters` 更改为类 `CommonQueryParams`:
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及 以上"
|
||||
|
||||
```Python hl_lines="9-13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
注意用于创建类实例的 `__init__` 方法:
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及 以上"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
...它与我们以前的 `common_parameters` 具有相同的参数:
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及 以上"
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
这些参数就是 **FastAPI** 用来 "处理" 依赖项的。
|
||||
|
||||
在两个例子下,都有:
|
||||
|
||||
* 一个可选的 `q` 查询参数,是 `str` 类型。
|
||||
* 一个 `skip` 查询参数,是 `int` 类型,默认值为 `0`。
|
||||
* 一个 `limit` 查询参数,是 `int` 类型,默认值为 `100`。
|
||||
|
||||
在两个例子下,数据都将被转换、验证、在 OpenAPI schema 上文档化,等等。
|
||||
|
||||
## 使用它
|
||||
|
||||
现在,您可以使用这个类来声明你的依赖项了。
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及 以上"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
**FastAPI** 调用 `CommonQueryParams` 类。这将创建该类的一个 "实例",该实例将作为参数 `commons` 被传递给你的函数。
|
||||
|
||||
## 类型注解 vs `Depends`
|
||||
|
||||
注意,我们在上面的代码中编写了两次`CommonQueryParams`:
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
最后的 `CommonQueryParams`:
|
||||
|
||||
```Python
|
||||
... = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
...实际上是 **Fastapi** 用来知道依赖项是什么的。
|
||||
|
||||
FastAPI 将从依赖项中提取声明的参数,这才是 FastAPI 实际调用的。
|
||||
|
||||
---
|
||||
|
||||
在本例中,第一个 `CommonQueryParams` :
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams ...
|
||||
```
|
||||
|
||||
...对于 **FastAPI** 没有任何特殊的意义。FastAPI 不会使用它进行数据转换、验证等 (因为对于这,它使用 `= Depends(CommonQueryParams)`)。
|
||||
|
||||
你实际上可以只这样编写:
|
||||
|
||||
```Python
|
||||
commons = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
..就像:
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及 以上"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
但是声明类型是被鼓励的,因为那样你的编辑器就会知道将传递什么作为参数 `commons` ,然后它可以帮助你完成代码,类型检查,等等:
|
||||
|
||||
<img src="/img/tutorial/dependencies/image02.png">
|
||||
|
||||
## 快捷方式
|
||||
|
||||
但是您可以看到,我们在这里有一些代码重复了,编写了`CommonQueryParams`两次:
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
**FastAPI** 为这些情况提供了一个快捷方式,在这些情况下,依赖项 *明确地* 是一个类,**FastAPI** 将 "调用" 它来创建类本身的一个实例。
|
||||
|
||||
对于这些特定的情况,您可以跟随以下操作:
|
||||
|
||||
不是写成这样:
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
...而是这样写:
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends()
|
||||
```
|
||||
|
||||
您声明依赖项作为参数的类型,并使用 `Depends()` 作为该函数的参数的 "默认" 值(在 `=` 之后),而在 `Depends()` 中没有任何参数,而不是在 `Depends(CommonQueryParams)` 编写完整的类。
|
||||
|
||||
同样的例子看起来像这样:
|
||||
|
||||
=== "Python 3.6 以及 以上"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 以及 以上"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
... **FastAPI** 会知道怎么处理。
|
||||
|
||||
!!! tip
|
||||
如果这看起来更加混乱而不是更加有帮助,那么请忽略它,你不*需要*它。
|
||||
|
||||
这只是一个快捷方式。因为 **FastAPI** 关心的是帮助您减少代码重复。
|
||||
|
|
@ -89,6 +89,7 @@ nav:
|
|||
- tutorial/body-updates.md
|
||||
- 依赖项:
|
||||
- tutorial/dependencies/index.md
|
||||
- tutorial/dependencies/classes-as-dependencies.md
|
||||
- tutorial/dependencies/sub-dependencies.md
|
||||
- tutorial/dependencies/dependencies-in-path-operation-decorators.md
|
||||
- tutorial/dependencies/global-dependencies.md
|
||||
|
|
|
|||
Loading…
Reference in New Issue