フォーマット文字列の辞書があれば、カスケード/再帰的な文字列補間を行いたいです。
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'}
結果は OK ですが、この実装では参照サイクルが検出されません。
たとえば、次の呼び出しは無限ループになります。
>>> interpolate({'home': '{home}'})
誰かが私により良い実装を与えることができますか?
編集:解決策
レオンの解決策は優れていてシンプルだと思います。セルジュ・ベレスタの解決策も同様です。
私はそれをそのように実装します:
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]]