フォーマット文字列の辞書が与えられた場合、 カスケード/再帰的文字列補間を行いたいと思います。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'}
結果はOKですが、この実装はリファレンス・サイクルを検出しません。
たとえば、次の呼び出しの結果、Infiniteループが発生します。
>>> interpolate({'home': '{home}'})
もっと良い実装をいただけますか?
EDIT:ソリューション
私はレオンのソリューションは、あまりにもセルジュ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]]
*「?誰が私より良い実装を与えることができます」* - それはSOのためではありません。あなたが解決しようとしている実際の問題は何ですか?実際には参照サイクルの入力がありますか? – jonrsharpe
* "私にはより良い実装を提供できますか?" * - 指定された入力に対して全く同じ結果を生成するだけですか? –
事実なら、私は一般的なソリューションを探しています。 exemplesはイラストレーションのためのものです。はい、フォルダを定義するユーザが - 典型的には設定ファイルにエラーを生じた場合、サイクルを繰り返すことができます: '' interpolate() ''関数がそれを見つけなければなりません。 –