实现无字符串参数的可变参数函数与方法链式调用构建API查询语句
解决方案:利用元类实现无字符串的API查询链式构建
核心思路是通过自定义元类拦截属性访问,将链式调用的属性名映射为API查询参数和参数值,同时处理多值参数的拼接逻辑(用|分隔)。以下是可运行的修正代码:
class APIMeta(type): def __new__(cls, name, bases, attrs): # 初始化参数存储容器和当前追踪的参数 attrs['_params'] = {} attrs['_current_param'] = None def __getattr__(self, attr): if attr == 'build': # 生成最终查询字符串 parts = [] for key, values in self._params.items(): val = '|'.join(values) if isinstance(values, list) else values parts.append(f"{key}={val}") return '&'.join(parts) if self._current_param is not None: # 收集当前参数的多值 if self._current_param not in self._params: self._params[self._current_param] = [] self._params[self._current_param].append(attr) return self else: # 标记下一个要赋值的参数名 self._current_param = attr return self attrs['__getattr__'] = __getattr__ return super().__new__(cls, name, bases, attrs) class API(metaclass=APIMeta): pass # 链式调用生成目标查询语句 query = API().meta.tokens.type.logintoken.write.patrol.build() print(query) # 输出: meta=tokens&type=logintoken|write|patrol
代码说明:
- APIMeta元类:动态注入属性拦截逻辑,所有未定义的属性访问都会被
__getattr__处理:- 访问
build时,将存储的参数键值对拼接为符合要求的查询字符串; - 若已有活跃参数(
_current_param不为空),则把当前属性名作为参数值加入列表; - 若没有活跃参数,则把当前属性名设为下一个要赋值的参数。
- 访问
- API类:仅需指定元类,无需额外业务代码,所有链式调用逻辑由元类接管。
- 调用逻辑:
meta.tokens对应设置meta=tokens,type.logintoken.write.patrol对应收集type的多值并以|分隔,最终通过build()输出完整查询语句。
这种设计完全规避了主逻辑中的硬编码字符串,严格遵循链式调用的设计意图,完美匹配Wikipedia Action API的参数格式要求。
内容的提问来源于stack exchange,提问作者Kim G'bril Jibin
相关产品推荐
相关产品推荐

