Страницы

Поиск по вопросам

понедельник, 9 декабря 2019 г.

«Каррирование» str.format

#python #python_3x #строки


Есть шаблон строки, который я хочу заполнить значениями за два (или за N) вызова
str.format():

template = 'foo{a}bar{b}buzz'


Сначала так:

step1 = template.format(a=' A ')
print (step1)

> foo A bar{b}buzz


Потом:

step2 = step1.format(b=' B ')
print(step2)

> foo A bar B 


Однако Python не позволяет передать в format() список меньшего размера или словарь
не со всеми значениями.

Можно ли как-то выполнить «каррирование», то есть частичный str.format()? (Я понимаю,
что это совсем не каррирование, поэтому кавычки. Grundy подсказывает, что это можно
называть «частичным применением»).



Разумеется, я могу сделать так:

'foo{a}bar{b}buzz'.format(a=' A ', b='{b}')


Но это грязный хак, мне он не нравится тем, что нужно каждый раз перечислять параметры,
то есть способ не универсален.

Ещё можно использовать чистое каррирование и создавать промежуточный объект-метод.
Но он не является строкой, его нельзя передать в какой-то сторонний метод, который
ждет именно строку.



Интересны решения для Python2 и Python 3.
    


Ответы

Ответ 1



В данном случае нужно не каррирование, а частичное применение. Для этого используется функция partial из модуля functools например: from functools import partial template = 'foo{a}bar{b}buzz'; fun = partial(template.format, a='w'); print( fun(b='dd') ); Repl.it

Ответ 2



Если в форматируемой строке подставляемые значения обрамлены пробелами, как в вопросе, то удобно использовать `string.Template'. from string import Template temp = Template('foo $a bar $b buzz') temp.safe_substitute(a='test') >>> 'foo test bar $b buzz' temp.substitute(a='test', b='val') >>> 'foo test bar val buzz' Если пробелов не должно быть, то уже не так красиво и надо учитывать, могут ли быть пробелы в подставляемой строке, или выбрать другой разделитель в Template: strfmt = 'foo{}bar{}buzz' temp = Template('$a $b') strfmt.format(*temp.safe_substitute(a='TEST').split())

Комментариев нет:

Отправить комментарий