Python开发API封装库时如何将函数全部参数传递生成请求数据?
可行的实现方案有以下三种,都可以保留显式参数定义和完整类型提示:
方案1:直接使用locals()获取参数(最简单)
在函数最开头调用locals()获取当前作用域的所有变量,此时作用域内只有传入的函数参数,不会有后续定义的变量污染,过滤掉self后就可以直接生成请求参数:
def create_project( self, client_id: int, name: str, is_billable: bool, bill_by: str, budget_by: str, code: Optional[str] = None, is_active: Optional[bool] = None, # 其余参数省略 ): # 必须在函数最开头获取,避免后续新增变量被加入参数列表 data = locals().copy() # 移除类方法自带的self参数 data.pop("self") # 可选操作:过滤掉值为None的可选参数,避免传给API冗余字段 data = {k: v for k, v in data.items() if v is not None} requests.post(url, headers=self.headers, data=data)
这种方案不需要额外依赖,代码量最少,适合单个独立的方法使用。
方案2:用dataclass/pydantic模型封装参数(可维护性最高)
如果你的封装库有大量类似的API方法,或者需要做参数校验,可以把所有参数定义为数据模型,既保留类型提示,转字典也非常方便:
from dataclasses import dataclass from typing import Optional # 统一管理参数定义 @dataclass class CreateProjectParams: client_id: int name: str is_billable: bool bill_by: str budget_by: str code: Optional[str] = None is_active: Optional[bool] = None # 其余参数省略
函数定义和调用逻辑:
def create_project(self, params: CreateProjectParams): data = params.__dict__ # 同样可以过滤None值 data = {k: v for k, v in data.items() if v is not None} requests.post(url, headers=self.headers, data=data) # 调用示例,IDE可以完整补全所有参数和类型提示 # client.create_project(CreateProjectParams(client_id=123, name="测试项目", ...))
这种方案适合参数复用多、需要参数校验的场景,后期修改参数只需要改模型定义即可。
方案3:用inspect模块获取函数签名(最稳妥)
如果担心locals()会被不小心加入的中间变量污染,可以用inspect模块显式获取函数定义的参数列表,再从当前作用域匹配取值:
import inspect def create_project( self, client_id: int, name: str, is_billable: bool, bill_by: str, budget_by: str, code: Optional[str] = None, is_active: Optional[bool] = None, # 其余参数省略 ): sig = inspect.signature(create_project) # 获取函数定义的所有参数名 param_names = [p for p in sig.parameters.keys() if p != "self"] data = {k: locals()[k] for k in param_names if locals()[k] is not None} requests.post(url, headers=self.headers, data=data)
这种方案不受函数内部变量的影响,参数匹配更准确,性能比前两种稍差,但普通业务场景完全感知不到差异。
内容的提问来源于stack exchange,提问作者dchoruzy
相关产品推荐
相关产品推荐

