如何封装dict.update()实现同时支持位置与关键字参数的函数
解决方案
你可以通过匹配dict.update()原生的参数定义逻辑实现两种传参的兼容,以下是全Python3版本兼容的实现:
parDict = {} parDict['a'] = 1 parDict['b'] = 2 parDict['group1.a'] = 3 def par(*args, **kwargs): # 此处可添加你的自定义校验逻辑 if len(args) > 1: raise TypeError(f"par() takes at most 1 positional argument but {len(args)} were given") # 先处理位置参数传入的字典/键值对可迭代对象 if args: parDict.update(args[0]) # 再处理关键字参数 parDict.update(kwargs)
效果验证
两种调用形式都可以正常执行,和原生update行为完全一致:
# 关键字参数传参 par(a=2, b=3) print(parDict) # 输出:{'a': 2, 'b': 3, 'group1.a': 3} # 字典传参 par({'group1.a':4}) print(parDict) # 输出:{'a': 2, 'b': 3, 'group1.a': 4} # 同时传两种参数也支持 par({'a':5}, c=6) print(parDict) # 输出:{'a': 5, 'b': 3, 'group1.a': 4, 'c': 6}
Python 3.8+ 简化写法
如果你的运行环境是Python3.8及以上,可以用仅限位置参数标记/简化写法,避免参数名冲突:
def par(x=None, /, **kwargs): # 自定义校验逻辑 if x is not None: parDict.update(x) parDict.update(kwargs)
自定义校验示例
你可以在执行update前先把所有待更新的内容收集到临时字典中,完成校验后再写入原字典:
def par(*args, **kwargs): to_update = {} if len(args) > 1: raise TypeError(f"par() takes at most 1 positional argument but {len(args)} were given") if args: to_update.update(args[0]) to_update.update(kwargs) # 示例校验:所有值必须为数字 for k, v in to_update.items(): if not isinstance(v, (int, float)): raise ValueError(f"参数{k}的值必须为数字类型") parDict.update(to_update)
内容的提问来源于stack exchange,提问作者janpeter
相关产品推荐
相关产品推荐

