Python如何从函数参数生成仅包含非None值的参数字典
解决方案
需求合理性说明
保留明确参数列表完全合理,是更符合Python最佳实践的做法。显式参数声明可以提供IDE自动补全、静态类型检查、清晰的接口定义,比模糊的**kwargs可维护性高得多,只有在参数确实动态不可预期的场景下才推荐使用**kwargs。
推荐实现方案
方案1:装饰器封装(最高效,一次实现到处复用)
这个方案不需要修改原有函数的核心逻辑,参数调整时也无需同步维护过滤代码,适合有大量同类需求的场景:
from functools import wraps from inspect import signature def filter_none_args(func): @wraps(func) def wrapper(*args, **kwargs): # 绑定当前调用的所有参数 bound_args = signature(func).bind(*args, **kwargs) # 填充默认值 bound_args.apply_defaults() # 过滤值为None的参数 func.filtered_args = {k: v for k, v in bound_args.arguments.items() if v is not None} return func(*args, **kwargs) return wrapper
使用方式:
@filter_none_args def foo(limit=None, offset=None, lower_bound=None, upper_bound=None): magic_dict = foo.filtered_args # 后续直接使用magic_dict即可 print(magic_dict) # 调用测试 foo(limit=5, lower_bound=100) # 输出:{'limit': 5, 'lower_bound': 100}
方案2:单函数内极简实现
如果只有单个函数需要该能力,不想引入装饰器,可以用inspect模块直接读取当前函数的参数列表,避免手动维护参数名:
from inspect import currentframe, getargvalues def foo(limit=None, offset=None, lower_bound=None, upper_bound=None): # 必须放在函数最开头,避免后续定义的变量干扰 _, _, _, values = getargvalues(currentframe()) magic_dict = {k: v for k, v in values.items() if v is not None} # 后续其他逻辑,新增变量不会影响magic_dict other_var = "test" print(magic_dict)
方案3:数据类封装(适合参数较多的场景)
如果参数本身是一组相关的配置项,推荐用数据类封装,逻辑更清晰,参数复用性更高:
from dataclasses import dataclass from typing import Optional @dataclass class FooParams: limit: Optional[int] = None offset: Optional[int] = None lower_bound: Optional[int] = None upper_bound: Optional[int] = None def to_non_none_dict(self): return {k: v for k, v in self.__dict__.items() if v is not None} def foo(params: FooParams): magic_dict = params.to_non_none_dict() print(magic_dict) # 调用测试 foo(FooParams(limit=5, lower_bound=100))
内容的提问来源于stack exchange,提问作者user12394023
相关产品推荐
相关产品推荐

