mirror of https://github.com/tiangolo/fastapi.git
🌐 Add Russian translation for `docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md` (#10410)
Co-authored-by: Vladislav Kramorenko <85196001+Xewus@users.noreply.github.com>
This commit is contained in:
parent
e0eaaee749
commit
3ca38568c1
|
|
@ -0,0 +1,478 @@
|
|||
# Классы как зависимости
|
||||
|
||||
Прежде чем углубиться в систему **Внедрения Зависимостей**, давайте обновим предыдущий пример.
|
||||
|
||||
## `Словарь` из предыдущего примера
|
||||
|
||||
В предыдущем примере мы возвращали `словарь` из нашей зависимости:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
Но затем мы получаем `словарь` в параметре `commons` *функции операции пути*. И мы знаем, что редакторы не могут обеспечить достаточную поддержку для `словаря`, поскольку они не могут знать их ключи и типы значений.
|
||||
|
||||
Мы можем сделать лучше...
|
||||
|
||||
## Что делает зависимость
|
||||
|
||||
До сих пор вы видели зависимости, объявленные как функции.
|
||||
|
||||
Но это не единственный способ объявления зависимостей (хотя, вероятно, более распространенный).
|
||||
|
||||
Ключевым фактором является то, что зависимость должна быть "вызываемой".
|
||||
|
||||
В 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.10+"
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="12-16"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="9-13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
Обратите внимание на метод `__init__`, используемый для создания экземпляра класса:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
...имеет те же параметры, что и ранее используемая функция `common_parameters`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
Эти параметры и будут использоваться **FastAPI** для "решения" зависимости.
|
||||
|
||||
В обоих случаях она будет иметь:
|
||||
|
||||
* Необязательный параметр запроса `q`, представляющий собой `str`.
|
||||
* Параметр запроса `skip`, представляющий собой `int`, по умолчанию `0`.
|
||||
* Параметр запроса `limit`, представляющий собой `int`, по умолчанию равный `100`.
|
||||
|
||||
В обоих случаях данные будут конвертированы, валидированы, документированы по схеме OpenAPI и т.д.
|
||||
|
||||
## Как это использовать
|
||||
|
||||
Теперь вы можете объявить свою зависимость, используя этот класс.
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
**FastAPI** вызывает класс `CommonQueryParams`. При этом создается "экземпляр" этого класса, который будет передан в качестве параметра `commons` в вашу функцию.
|
||||
|
||||
## Аннотация типа или `Depends`
|
||||
|
||||
Обратите внимание, что в приведенном выше коде мы два раза пишем `CommonQueryParams`:
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
Последний параметр `CommonQueryParams`, в:
|
||||
|
||||
```Python
|
||||
... Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
...это то, что **FastAPI** будет использовать, чтобы узнать, что является зависимостью.
|
||||
|
||||
Из него FastAPI извлечёт объявленные параметры и именно их будет вызывать.
|
||||
|
||||
---
|
||||
|
||||
В этом случае первый `CommonQueryParams`, в:
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, ...
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams ...
|
||||
```
|
||||
|
||||
...не имеет никакого специального значения для **FastAPI**. FastAPI не будет использовать его для преобразования данных, валидации и т.д. (поскольку для этого используется `Depends(CommonQueryParams)`).
|
||||
|
||||
На самом деле можно написать просто:
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python
|
||||
commons = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
...как тут:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
|
||||
Но объявление типа приветствуется, так как в этом случае ваш редактор будет знать, что будет передано в качестве параметра `commons`, и тогда он сможет помочь вам с автодополнением, проверкой типов и т.д:
|
||||
|
||||
<img src="/img/tutorial/dependencies/image02.png">
|
||||
|
||||
## Сокращение
|
||||
|
||||
Но вы видите, что здесь мы имеем некоторое повторение кода, дважды написав `CommonQueryParams`:
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
Для случаев, когда зависимостью является *конкретный* класс, который **FastAPI** "вызовет" для создания экземпляра этого класса, можно использовать укороченную запись.
|
||||
|
||||
|
||||
Вместо того чтобы писать:
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
...следует написать:
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends()]
|
||||
```
|
||||
|
||||
=== "Python 3.6 без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends()
|
||||
```
|
||||
|
||||
Вы объявляете зависимость как тип параметра и используете `Depends()` без какого-либо параметра, вместо того чтобы *снова* писать полный класс внутри `Depends(CommonQueryParams)`.
|
||||
|
||||
Аналогичный пример будет выглядеть следующим образом:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
|
||||
...и **FastAPI** будет знать, что делать.
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Если это покажется вам более запутанным, чем полезным, не обращайте внимания, это вам не *нужно*.
|
||||
|
||||
Это просто сокращение. Потому что **FastAPI** заботится о том, чтобы помочь вам свести к минимуму повторение кода.
|
||||
Loading…
Reference in New Issue