所謂的泛型, 就是將資料型別作為引數進行傳遞, 即在我們用的時候確定資料型別, 這是一種在物件導向語言中經常使用的特性
以sqlalchemy舉例比如: 我們統一寫個將資料儲存到資料庫的介面, 只有將
資料庫鏈結
表物件
資料
傳入即可, 返回的是表物件的例項
, 為了讓ide可以識別返回物件, 我們可以使用泛型
這裡需要用到:
typing
的typevar
和type
typevar
是型別變數, 主要用於泛型型別與泛型函式定義的引數, 第乙個引數是名稱,bound
引數用於規定該型別為bound
值的子類
type[c]
的形式為協變數, 表明c
的所有子類都應使用與c
相同的 構造器簽名 及 類方法簽名, 假如我們需要返回泛型型別的話, 需要用到
更多使用方法, 見: typing使用使用了
pydantic
規範要建立資料的型別
關於pydantic
的一般使用, 見: pydantic使用
from typing import typevar, type
from sqlalchemy.orm import session
from pydantic import basemodel
from orm.models import category
from orm.schemas import writecategorymodel
# 定義型別
modelt = typevar("modelt")
datat = typevar("datat", bound=basemodel) # bound表明該類為basemodel的子類
"""為節省空間, 表結構和模型不展示
"""def create_category(session: session, data: writecategorymodel) -> type[category]:
cate_obj = s**e_one_to_db(session=session, model_class=category, data=data)
return cate_obj
def s**e_one_to_db(session: session, model_class: modelt, data: datat) -> modelt:
"""儲存一條到資料庫
:param session: sqlalchemy session
:param model_class: sqlalchemy模型類
:param data: pydantic模型物件
:return: 對應sqlalchemy模型類的物件
"""try:
obj = model_class(**data.dict())
session.add(obj)
session.commit()
# 手動將 資料 重新整理到資料庫
session.refresh(obj)
return obj
except exception as e:
# 別忘記發生錯誤時回滾
session.rollback()
raise e
在使用pydantic時, 亦可以使用泛型比如: 在
fastapi
中返回統一返回格式為:
我們的data
可能是列表或物件, 而且對應的pydantic
模型也不一樣, 這時我們就可以使用泛型了
router = apirouter(prefix="/test", tags=["測試泛型"])
# 為了方便, 在這裡定義pydantic模型
datat = typevar("datat")
class genericresponse(genericmodel, generic[datat]):
"""通用返回資料
"""status: bool
msg: str
data: optional[datat] = none # 可能連data都沒有
# 設定response_model_exclude_unset=true即可
class bookmodel(basemodel):
id: int
name: str
# 偽資料
fake_book_data = [,,
,,,]@router.get("/books", response_model=genericresponse[list[bookmodel]])
def get_books():
return
@router.get("/books/", response_model=genericresponse[bookmodel])
def retrieve_book(bid: int):
for item in fake_book_data:
if item.get("id") == bid:
return
# 不存在
raise httpexception(status_code=status.http_404_not_found, detail="該書不存在")
訪問/docs
頁面, 成功通過測試
C 泛型 使用泛型List
一 泛型的優點 效能高。從前面的例子可以看出使用不需進行型別轉換,可以避免裝箱和拆箱操作,提高效能。型別安全。泛型集合對其儲存物件進行了型別約束,不是定義時宣告的型別,是無法儲存到泛型集合中的,保證了資料型別的安全。重用。使用泛型型別可以最大限度地重用 保護型別的安全以及提高效能。使用泛型 使用泛型...
C 泛型 使用泛型List
一 泛型的優點 效能高。從前面的例子可以看出使用不需進行型別轉換,可以避免裝箱和拆箱操作,提高效能。型別安全。泛型集合對其儲存物件進行了型別約束,不是定義時宣告的型別,是無法儲存到泛型集合中的,保證了資料型別的安全。重用。使用泛型型別可以最大限度地重用 保護型別的安全以及提高效能。使用泛型 使用泛型...
泛型結構使用大全(泛型類 泛型介面)
1 泛型類可能有多個引數,此時應將多個引數一起放到尖括號內,比如 2 泛型類的構造器如下 public genericclass 錯誤示例 public genericclass 3 例項化後,操作原來泛型位置的結構必須與指定的泛型型別一致。4 泛型不同的引用不能互相賦值。儘管在編譯時arrayli...