
fastapi的依赖注入系统是其强大功能之一,它允许开发者声明函数所需的依赖项,并由框架在请求处理前自动提供。fastapi.depends是实现这一机制的关键。当您将一个函数传递给depends时,fastapi期望的是一个可调用对象(callable object),即函数的引用本身,而不是该函数执行后的结果。
考虑以下数据库会话依赖函数 get_db:
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()这个函数是一个生成器函数。它使用yield关键字来提供一个数据库会话db,并在请求处理完成后,通过finally块确保数据库会话被正确关闭。这种模式在FastAPI中非常常见,用于管理资源(如数据库连接、文件句柄等)的生命周期。
当您在路由处理函数中这样使用Depends时:
@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db())):
# ...问题出在Depends(get_db())这一行。这里的get_db()是对get_db函数的立即调用。由于get_db是一个生成器函数,调用它会立即返回一个生成器对象(generator object),而不是函数本身。
因此,Depends接收到的是一个生成器对象,而不是一个可调用的函数引用。FastAPI的依赖注入系统在运行时会尝试“调用”传递给Depends的对象来获取依赖值。当它尝试调用一个生成器对象时,就会抛出TypeError: <generator object ...> is not a callable object,因为它期望的是一个可以被直接调用的函数。
要解决这个问题,您需要将get_db函数的引用传递给Depends,而不是调用它的结果。正确的做法是:
@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db)):
# ...注意Depends(get_db)与Depends(get_db())的区别:
以下是修正后的home.py关键部分:
from fastapi import Depends, APIRouter, Request
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from starlette.responses import HTMLResponse
from database import SessionLocal, engine
from models import Base
router = APIRouter()
templates = Jinja2Templates(directory="templates", autoescape=False)
Base.metadata.create_all(bind=engine)
def get_db():
"""
依赖函数,用于获取并管理数据库会话。
使用 yield 确保会话在请求结束后被关闭。
"""
db = SessionLocal()
try:
yield db
finally:
db.close()
@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db)): # 修正:传递函数引用
"""
获取所有技能的路由,并渲染到 home.html 模板。
"""
# 假设 db.query() 后面会跟具体的查询,例如 db.query(YourModel).all()
# 这里为了示例,我们假设 db.query() 返回一个可迭代对象
all_items = db.query() # 实际应用中应替换为具体的查询
return templates.TemplateResponse("home.html", {"request": request, "show": all_items})
database.py (保持不变)
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker SQL_ALCHEMY_DATABASE_URL = "postgresql://postgres:password@localhost/DatabaseName" engine = create_engine(SQL_ALCHEMY_DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base()
main.py (保持不变)
from fastapi import FastAPI
import models
from database import engine
from routers import home
from starlette.staticfiles import StaticFiles
app = FastAPI()
models.Base.metadata.create_all(bind=engine)
app.mount("/static", StaticFiles(directory="static"), name="static")
app.include_router(home.router)def get_current_user(token: str = Depends(oauth2_scheme)):
# ... 验证 token 并返回用户
return user这里oauth2_scheme也是一个Depends对象,get_current_user的参数token将由oauth2_scheme提供。
TypeError: <generator object ...> is not a callable object错误是FastAPI依赖注入中一个常见的陷阱,它源于将函数调用的结果而非函数引用传递给了Depends。通过理解Depends期望的是一个可调用对象,并始终传递函数本身的引用,您可以避免此类错误,并充分利用FastAPI强大且灵活的依赖注入系统来构建健壮的应用。正确使用依赖注入不仅能提高代码的可读性和可维护性,还能有效管理应用中的资源。
以上就是FastAPI依赖注入TypeError:Depends函数调用错误解析与修正的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号