在之前的依赖注入中使用的依赖项都是函数,是不是就意味着依赖项必需是函数呢?当然不是,决定是否可以当作依赖项的关键因素就是是否是"可调用"。
如果一个对象是“可调用”的,那么它就可以作为依赖项。所以显然函数和类都是可被调用的,那么类如何作为依赖项。
from typing import Optional from fastapi import FastAPI app = FastAPI() class CommonQueryParams: def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 10): self.q = q self.skip = skip self.limit = limit
显然,类被调用后是一个实例,上述CommonQueryParams类可以作为一个依赖项,然后将之前的参数传给这个类。
现在可以使用这个类依赖项:
from typing import Optional from fastapi import Depends, FastAPI app = FastAPI() items = [ {"name": "apple", "price": "1.12"}, {"name": "pear", "price": "3.14"} ] class CommonQueryParams: def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 10): self.q = q self.skip = skip self.limit = limit @app.get("/items/") async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)): response = {} if commons.q: response.update({"q": commons.q}) result = items[commons.skip:commons.skip + commons.limit] response.update({"result": result}) return response
这与函数作为依赖项大同小异,当请求到来后,FastAPI调用依赖类CommonQueryParams,这个类创建实例并且实例作为参数传递给路径操作函数。
当使用过函数作为依赖项,并且在路径操作函数中进行类型声明是这样的:
... @app.get("/items/") async def read_items(commons: dict = Depends(common_parameters)): return commons ...
dict为类型声明,Depends中传递依赖项。在类中也使用了一样的方式:
... @app.get("/items/") async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)): response = {} if commons.q: response.update({"q": commons.q}) result = items[commons.skip:commons.skip + commons.limit] response.update({"result": result}) return response ...
在这里,实际上真正有作用的是Depends中传递的CommonQueryParams,FastAPI将会抽取声明的参数以及真正调用。
这里的CommonQueryParams并没有任何特殊的意义,FastAPI不会使用它进行数据转换、校验等。
所以完全可以写成以下形式:
commons = Depends(CommonQueryParams)
或者另一种写法就是声明依赖类为commons参数的类型,而Depends作为函数参数的默认值。
commons: CommonQueryParams = Depends()