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
(未顯示)添加一堆額外的邏輯。有沒有更簡單的解決方法,不會在使用時膨脹語法?
在這種情況下,如果有多餘的參數,我也希望一個匹配失敗 - 這樣,意外的屬性就不會被默默地丟失。 –