Чи існує Python, еквівалентний рядковій інтерполяції Рубі?


343

Рубін приклад:

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-рядків", наприклад

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

Я розумію основну суть цього, але я не повністю розумію всі додаткові символи та текст, знайдений у прикладі в документації, однак. Чому тут використовується перетворення в рядок:% (мова) s Що означає 3 у "03d"? Чому після рядка є% \? Призначення змінних (якщо вони насправді є змінними) після виразу друку, також мене бентежить. Вибачте, якщо це біль!
Каста

1
Два основних формати, використані в прикладі, є %sдля рядка та %03dдля числа, доповненого 3-ма цифрами з провідними нулями. Це можна було просто написати print "%s has %03d" % ("Python", 2). Потім у прикладі використовується введення ключа в картону в дужках, після %чого це спосіб дати значущі імена заповнювачів, а не покладатися на їх порядок у рядку. Потім ви передаєте словник, який відображає назви ключових значень їх значенням. Ось чому Sven використовує locals()функцію, яка повертає дікт, що містить усі ваші локальні змінні, тому він буде відображати nameзначення імені
mikej

Перше мене збентежило необхідне використання типу конверсії. Отже, використовуючи термінологію документації. % Запускає специфікатор. Не існує прапор конверсії для (мова), лише тип конверсії (тривалість 's'); (число), однак, має один (або два) прапори перетворення, який дорівнює "0" (і "3" відповідно). 'D' - тип перетворення і означає, що це ціле число. Я правильно зрозумів?
Каста

@Caste: Так, це в основному правильно. Зауважте, що ви завжди можете використовувати 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)
Corey Goldberg

9
Лише зауваження: число в {}мені може бути усунене.
розіграш

32

Я розробив пакет інтерпірування , який дозволяє інтерполяцію рядків у 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: Ні, поки рядки відомі під час компіляції.
Clément

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
як я можу зробити це таким чином за допомогою двох змінних?
Хуліо Марінс

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}')

Зауважте, що я ненавиджу Spongebob, тому писати це було трохи болісно. :)


Thx для цієї посилання на Spongebob (/ distaste): треба зараз це підняти.
javadba

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.