如何强制Mako函数要求使用命名参数?
在Mako模板中强制使用命名参数的解决方案
Mako的<%def>语法并不支持Python里的*符号来强制后续参数必须以命名方式传入,它会直接忽略这个语法。要实现强制命名参数的需求,可以用以下两种方法:
方案一:通过**kwargs手动校验
这种方法无需额外依赖,直接在<%def>内部检查参数是否以命名方式传入:
from mako.template import Template s = """\ <%def name="myfunc(a, b, **kwargs)"> % if 'c' not in kwargs or 'd' not in kwargs: <% raise TypeError("myfunc() requires 'c' and 'd' to be passed as named arguments") %> % endif <% c = kwargs['c'] d = kwargs['d'] %> I want to require that arguments c=${c} and d=${d} are named </%def> # 错误调用会抛出TypeError # ${myfunc(1,2,3,4)} # 正确调用 ${myfunc(1,2,c=3,d=4)} """ print(Template(s).render())
当尝试用位置参数传入c或d时,它们不会被纳入kwargs,此时会触发TypeError,达到强制命名的效果。
方案二:借助Python函数签名校验
利用Python原生的inspect.signature来校验参数格式,完全贴合Python的强制命名参数语法:
from mako.template import Template s = """\ <% from inspect import signature # 定义符合原生Python语法的辅助函数,用*强制c、d为命名参数 def _myfunc(a, b, *, c, d): return f"I want to require that arguments c={c} and d={d} are named" # 包装函数,负责校验参数格式 def myfunc(*args, **kwargs): sig = signature(_myfunc) try: bound_args = sig.bind(*args, **kwargs) bound_args.apply_defaults() except TypeError as e: raise e return _myfunc(*bound_args.args, **bound_args.kwargs) %> # 错误调用会抛出TypeError # ${myfunc(1,2,3,4)} # 正确调用 ${myfunc(1,2,c=3,d=4)} """ print(Template(s).render())
这种方法复用了Python原生的参数校验逻辑,适合参数规则复杂的场景,错误提示也和原生Python保持一致。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

