掃二維碼與項目經理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯網交流
在深入研究依賴注入系統之前,讓我們升級前面的例子。

在前面的示例中,我們dict從我們的依賴項(“可靠”)中返回 a :
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
但是隨后我們在路徑操作函數dict的參數commons中得到了一個。
而且我們知道編輯器不能為dicts提供很多支持(比如補全),因為他們無法知道它們的鍵和值類型。
我們可以做得更好...
到目前為止,您已經看到了聲明為函數的依賴項。
但這不是聲明依賴項的唯一方法(盡管它可能更常見)。
關鍵因素是依賴項應該是“可調用的”。
Python 中的“可調用”是 Python 可以像函數一樣“調用”的任何東西。
因此,如果您有一個對象something(可能不是函數)并且您可以“調用”它(執(zhí)行它),例如:
something()
或者
something(some_argument, some_keyword_argument="foo")
那么它是一個“可調用的”。
您可能會注意到,要創(chuàng)建 Python 類的實例,您使用相同的語法。
例如:
class Cat:
def __init__(self, name: str):
self.name = name
fluffy = Cat(name="Mr Fluffy")
在這種情況下,fluffy是類的一個實例Cat。
而要創(chuàng)造fluffy,你就是在“呼喚” Cat。
因此,Python 類也是一個可調用的.
然后,在FastAPI 中,您可以使用 Python 類作為依賴項。
FastAPI 實際檢查的是它是“可調用的”(函數、類或其他任何東西)和定義的參數。
如果在FastAPI 中傳遞“可調用”作為依賴項,它將分析該“可調用”的參數,并以與路徑操作函數的參數相同的方式處理它們。包括子依賴。
這也適用于根本沒有參數的可調用對象。與沒有參數的路徑操作函數相同。
然后,我們可以將依賴項“可靠”common_parameters從上面更改為類CommonQueryParams:
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
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})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
注意__init__用于創(chuàng)建類的實例的方法:
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
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})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
...它具有與我們之前相同的參數common_parameters:
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
這些參數是FastAPI將用來“解決”依賴關系的。
在這兩種情況下,它將具有:
在這兩種情況下,數據都將被轉換、驗證、記錄在 OpenAPI 模式等上。
現在您可以使用此類聲明您的依賴項。
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
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})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
FastAPI調用CommonQueryParams該類。這將創(chuàng)建該類的“實例”,并且該實例將作為參數傳遞commons給您的函數。
注意我們CommonQueryParams在上面的代碼中是如何寫兩次的:
commons: CommonQueryParams = Depends(CommonQueryParams)
最后CommonQueryParams,在:
... = Depends(CommonQueryParams)
...是FastAPI實際用來知道什么是依賴項的。
FastAPI 將從中提取聲明的參數,這就是 FastAPI 將實際調用的內容。
在這種情況下,第一個CommonQueryParams, 在:
commons: CommonQueryParams ...
...對FastAPI沒有任何特殊含義。FastAPI 不會將它用于數據轉換、驗證等(因為它正在= Depends(CommonQueryParams)為此使用 )。
你實際上可以只寫:
commons = Depends(CommonQueryParams)
..如:
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons=Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
但是鼓勵聲明類型,因為這樣您的編輯器將知道將作為參數傳遞的內容commons,然后它可以幫助您完成代碼完成、類型檢查等:
但是你看到我們這里有一些代碼重復,寫了CommonQueryParams兩次:
commons: CommonQueryParams = Depends(CommonQueryParams)
FastAPI為這些情況提供了一種快捷方式,在這種情況下,依賴項特別是一個類,FastAPI將“調用”以創(chuàng)建類本身的實例。
對于這些特定情況,您可以執(zhí)行以下操作:
而不是寫:
commons: CommonQueryParams = Depends(CommonQueryParams)
...你寫:
commons: CommonQueryParams = Depends()
你聲明依賴作為參數的類型,并使用Depends()其“默認”值(即后=),該函數的參數,在沒有任何參數Depends(),而不必編寫完整的類再次里面的Depends(CommonQueryParams)。
同樣的例子看起來像:
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends()):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
...而FastAPI會知道該怎么做。
提示
如果這看起來更令人困惑而不是有用,請忽略它,您不需要它。
這只是一個捷徑。因為FastAPI關心幫助您最大程度地減少代碼重復。

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯網交流