Есть ли Python, эквивалентный строковой интерполяции Ruby?


343

Пример Ruby:

name = "Spongebob Squarepants"
puts "Who lives in a Pineapple under the sea? \n#{name}."

Успешная конкатенация строк Python кажется мне многословной.


2
Проблема здесь в том, что nameв строке лежит локальная переменная, а в Python вы должны явно передавать словарь локальных переменных в формататор строк, если вы хотите, чтобы они их использовали.
— Катриэль

Это была не оригинальная проблема, но спасибо. Ваш комментарий дал мне немного лучшее понимание области видимости (с чем я все еще справляюсь). :)
— Каста

1
Что вы думаете об этом, тогда? stackoverflow.com/questions/16504732/…
— SalchiPapa


2
См. Stackoverflow.com/a/33264516/55721 для этой точной функции в 3.6
— dss539

Ответы:


413

В Python 3.6 будет добавлена интерполяция буквенных строк, аналогичная интерполяции строк в Ruby. Начиная с этой версии Python (выпуск которой запланирован на конец 2016 года), вы сможете включать выражения в "f-strings", например:

name = "Spongebob Squarepants"
print(f"Who lives in a Pineapple under the sea? {name}.")

До 3.6 самый близкий к этому

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? %(name)s." % locals())

%Оператор может быть использован для интерполяции строк в Python. Первый операнд - это строка для интерполяции, второй может иметь разные типы, включая «отображение», отображение имен полей на значения, которые должны быть интерполированы. Здесь я использовал словарь локальных переменных locals()для сопоставления имени поляname с его значением в качестве локальной переменной.

Тот же код, использующий .format()метод последних версий Python, будет выглядеть так:

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? {name!s}.".format(**locals()))

Также есть string.Templateкласс:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.")
print(tmpl.substitute(name="Spongebob Squarepants"))

@Caste см. Здесь: docs.python.org/library/stdtypes.html#string-formatting и оставьте дополнительный комментарий, если вам нужна дополнительная информация
— mikej

Я понимаю основную суть этого, однако я не полностью понимаю все дополнительные символы и текст, найденные в примере в документации. Почему здесь используется функция преобразования в строку:% (language) s Что означают 3 в «03d»? Почему после строки есть% \? Присвоение переменных (если они фактически являются переменными) после выражения print меня также смущает. Извините, если это боль!
— Каста

1
В этом примере используются два основных формата %sдля строки и %03dдля числа, дополненного до 3 цифр начальными нулями. Это может быть просто написано print "%s has %03d" % ("Python", 2). Затем в этом примере в скобках %ставится ключ сопоставления, после которого указывается значащие имена заполнителей, а не полагается на их порядок в строке. Затем вы передаете словарь, который сопоставляет имена ключей с их значениями. Вот почему Свен использует locals()функцию, которая возвращает dict, содержащий все ваши локальные переменные, поэтому он сопоставляется nameсо значением name
— mikej

Сначала меня смутило обязательное использование типа конверсии. Итак, используя терминологию документации. % Запускает спецификатор. Для (языка) нет флага конверсии, только тип конверсии (завершающий 's'); (число), однако, имеет один (или два) флага преобразования, который равен '0' (и '3' соответственно). «D» является типом преобразования и означает, что это целое число. Правильно ли я понял?
— Каста

@ Каста: Да, это в принципе правильно. Обратите внимание, что вы всегда можете использовать sв качестве типа преобразования - Python может преобразовать практически что угодно в строку. Но, конечно, вы потеряете специальные возможности форматирования других типов преобразования.
— Свен Марнах

143

Начиная с Python 2.6.X вы можете использовать:

"my {0} string: {1}".format("cool", "Hello there!")

27
Обратите внимание, что %оператор для интерполяции строк не рекомендуется в Python 3.x. docs.python.org/dev/py3k/whatsnew/… объявляет о планах отказаться от %начиная с версии 3.1, но этого не произошло.
— Свен Марнач

8
% -синтаксис все еще живет в Python 3 (не рекомендуется в Python 3.2)
— Кори Голдберг

9
Просто примечание: номер в {}может меня исключить.
— ничья

32

Я разработал пакет interpy , который позволяет интерполировать строки в Python .

Просто установите его через pip install interpy. А затем добавьте строку# coding: interpy в начале ваших файлов!

Пример:

#!/usr/bin/env python
# coding: interpy

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n#{name}."

3
Это кажется действительно небезопасным.
— d33tah

@ d33tah: Нет, пока строки известны во время компиляции.
— Климент

28

Строковая интерполяция Python похожа на printf () в C

Если вы попытаетесь:

name = "SpongeBob Squarepants"
print "Who lives in a Pineapple under the sea? %s" % name

Тег %sбудет заменен на nameпеременную. Вы должны взглянуть на теги функции печати: http://docs.python.org/library/functions.html


1
Как я могу сделать это с 2 переменными?
— Хулио Маринс

16
@JulioMarins Используйте кортеж: print "First is %s, second is %s" % (var1, var2).
— kirbyfan64sos

28

Строковая интерполяция будет включена в Python 3.6, как указано в PEP 498 . Вы сможете сделать это:

name = 'Spongebob Squarepants'
print(f'Who lives in a Pineapple under the sea? \n{name}')

Обратите внимание, что я ненавижу Спанч Боба, поэтому писать это было немного больно. :)


Спасибо за эту ссылку Спанч Боба (/ distaste): сейчас надо это сказать.
— Джавадба

4

Вы также можете иметь это

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n{name}.".format(name=name)

http://docs.python.org/2/library/string.html#formatstrings


Я не верю, что ОП предназначено #для печати. Они просто используют синтаксис Ruby.
— Jaynp

Ты прав. Я отредактировал ответ. Я не знаком с Руби, поэтому думал, что #персонаж будет напечатан.
— Цюань до

3
import inspect
def s(template, **kwargs):
    "Usage: s(string, **locals())"
    if not kwargs:
        frame = inspect.currentframe()
        try:
            kwargs = frame.f_back.f_locals
        finally:
            del frame
        if not kwargs:
            kwargs = globals()
    return template.format(**kwargs)

Использование:

a = 123
s('{a}', locals()) # print '123'
s('{a}') # it is equal to the above statement: print '123'
s('{b}') # raise an KeyError: b variable not found

PS: производительность может быть проблемой. Это полезно для локальных сценариев, а не для рабочих журналов.

Дублированный:


2

Для старого Python (проверено на 2.4) верхнее решение указывает путь. Ты можешь сделать это:

import string

def try_interp():
    d = 1
    f = 1.1
    s = "s"
    print string.Template("d: $d f: $f s: $s").substitute(**locals())

try_interp()

И вы получаете

d: 1 f: 1.1 s: s

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.