1
我正在编写一个脚本来将ColdFusion CFML代码转换为CFScript代码。在许多地方,它会带属性的字典,通过功能的列表中查找,并调用第一个其参数匹配给定的属性与字典作为关键字ARGS:命名位置参数“from”
import inspect
def invokeFirst(attributes, *handlers):
given_args = set(attributes)
for handler in handlers:
meta = inspect.getargspec(handler)
allowed_args = set(meta.args)
required_args = set(meta.args[:-len(meta.defaults)]) if meta.defaults else meta.args
if required_args <= given_args and (meta.keywords or given_args <= allowed_args):
return handler(**attributes)
raise TypeError("Can't invoke with arguments {}.".format(str(given_args)))
使用示例:
def replaceLoop(tag):
forIn = 'for (var {item} in {collection}) {{'
return invokeFirst(tag.attributes,
lambda item, collection: forIn.format(item=bare(item) , collection=collection),
lambda index, array : forIn.format(item=bare(index), collection=index),
lambda _from, to, index:
'for (var {index} = {min}; {index} <= {max}; {index}++) {{'.format(
index=bare(index), min=_from, max=to,
),
)
现在,因为from
不是有效的参数名称,所以我必须在lambda表达式中加前缀,并向invokeFirst
(未显示)添加一堆额外的逻辑。有没有更简单的解决方法,不会在使用时膨胀语法?
在这种情况下,如果有多余的参数,我也希望一个匹配失败 - 这样,意外的属性就不会被默默地丢失。 –