给定一个格式字符串字典, 我想要做级联/递归字符串插值。在python中级联字符串插值
FOLDERS = dict(home="/home/user",
workspace="{home}/workspace",
app_project="{workspace}/{app_name}",
app_name="my_app")
我开始用这个实现:
def interpolate(attrs):
remain = [k for k, v in attrs.items() if "{" in v]
while remain:
for k in remain:
attrs[k] = attrs[k].format(**attrs)
remain = [k for k in remain if "{" in attrs[k]]
的interpolate()
功能首先选择的格式字符串。 然后,它替换字符串,直到没有更多的格式字符串保留。
当我打电话用下面的Python字典这个功能,我得到:
>>> import pprint
>>> pprint.pprint(FOLDERS)
{'app_name': 'my_app',
'app_project': '/home/user/workspace/my_app',
'home': '/home/user',
'workspace': '/home/user/workspace'}
结果是确定的,但这种做法不检测的参考周期。
例如,以下调用导致无限循环!
>>> interpolate({'home': '{home}'})
任何人都可以给我一个更好的实施吗?
编辑:解
我认为莱昂的解决方案是好的,简单,塞尔Bellesta过的一个。
我将实现这样的说法:
def interpolate(attrs):
remain = [k for k, v in attrs.items() if "{" in v]
while remain:
for k in remain:
attrs[k] = attrs[k].format(**attrs)
fmt = '{' + k + '}'
if fmt in attrs[k]: # check for reference cycles
raise ValueError("Reference cycle found for '{k}'!".format(k=k))
remain = [k for k in remain if "{" in attrs[k]]
*“?谁能给我一个更好的实施” * - 这不是什么意思。你试图解决的实际问题是什么?你真的会得到任何参考周期的输入吗? – jonrsharpe
*“任何人都可以给我一个更好的实现?”* - 它只需要为给定的输入产生完全相同的结果? –
如果其实我正在寻找一个通用的解决方案。这些例子仅用于说明。是的,如果定义文件夹的用户在 - 通常 - 配置文件中发生错误,我们可以有循环:''interpolate()''函数应该找到它。 –