Учитывая словарь строк формата, Я хочу сделать каскадную/рекурсивную интерполяцию строк.Каскадная строковая интерполяция в 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}'})
Может ли кто-нибудь дать мне лучшую реализацию?
EDIT: решение
Я думаю, что решение Леона хорошо и просто, один из Serge 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() '' должна найти ее. –