Existe um Python equivalente à interpolação de string do Ruby?

343

Exemplo de Ruby:

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

A concatenação bem-sucedida de strings Python é aparentemente detalhada para mim.

Casta
fonte
2
O problema aqui é que nameé uma variável local que está na string e, no Python, você precisa passar explicitamente o dicionário de variáveis ​​locais para o formatador de string, se quiser usá-las.
Katriel
Esta não era a questão original, mas obrigado. Seu comentário me deu uma compreensão um pouco melhor do escopo variável (algo com o qual ainda estou ganhando terreno). :)
Casta
11
O que você acha sobre este, então? stackoverflow.com/questions/16504732/…
SalchiPapa
PEP 215 - Interpolação de strings - substituída por python.org/dev/peps/pep-0292
Mr_and_Mrs_D 4/15/15
2
Consulte stackoverflow.com/a/33264516/55721 para obter este recurso exato em 3.6
dss539

Respostas:

413

O Python 3.6 adicionará interpolação literal de strings semelhante à interpolação de strings do Ruby. Começando com essa versão do Python (que está programada para ser lançada até o final de 2016), você poderá incluir expressões em "f-strings", por exemplo

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

Antes da 3.6, o mais próximo que você pode chegar disso é

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

O %operador pode ser usado para interpolação de cadeias de caracteres em Python. O primeiro operando é a string a ser interpolada, o segundo pode ter tipos diferentes, incluindo um "mapeamento", mapeando os nomes dos campos para os valores a serem interpolados. Aqui eu usei o dicionário de variáveis ​​locais locals()para mapear o nome do campo namepara seu valor como uma variável local.

O mesmo código usando o .format()método das versões recentes do Python ficaria assim:

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

Há também a string.Templateclasse:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.")
print(tmpl.substitute(name="Spongebob Squarepants"))
Sven Marnach
fonte
@Caste veja aqui: docs.python.org/library/stdtypes.html#string-formatting e poste um comentário de acompanhamento se precisar de mais detalhes #
mikej
Eu entendo a essência básica disso, mas não compreendo completamente todos os símbolos e textos adicionais encontrados no exemplo na documentação. Por que o uso de converter em string aqui:% (language) s O que o 3 em '03d' significa? Por que depois da string existe% \? A atribuição de variáveis ​​(se são de fato variáveis) após a expressão de impressão também me confunde. Desculpe se isso é uma dor!
Caste
11
Os dois formatos básicos usados ​​no exemplo são %spara uma string e %03dpara um número preenchido com 3 dígitos com zeros à esquerda. Poderia ser escrito print "%s has %03d" % ("Python", 2). O exemplo, em seguida, utiliza uma chave de mapeamento entre colchetes, após a %qual é uma maneira de fornecer aos espaços reservados nomes significativos em vez de confiar na ordem deles na string. Você passa um dicionário que mapeia os nomes das chaves para seus valores. É por isso que Sven está usando a locals()função que retorna um ditado contendo todas as suas variáveis ​​locais, para que ele seja name
mapeado
O uso necessário de um tipo de conversão foi o que primeiro me confundiu. Então, usando a terminologia da documentação. O% inicia o especificador. Não há sinalizador de conversão para (idioma), apenas um tipo de conversão (o final 's'); (número), no entanto, possui um (ou dois) sinalizadores de conversão que são '0' (e '3' respectivamente). O 'd' é o tipo de conversão e significa que é um número inteiro. Eu entendi corretamente?
Caste
@ Cream: Sim, isso é basicamente certo. Observe que você sempre pode usar a scomo um tipo de conversão - o Python pode converter praticamente qualquer coisa em uma string. Mas é claro que você perderia os recursos especiais de formatação de outros tipos de conversão.
Sven Marnach
143

Desde o Python 2.6.X, você pode querer usar:

"my {0} string: {1}".format("cool", "Hello there!")
EinLama
fonte
27
Observe que o %operador para interpolação de cadeias não é preterido no Python 3.x. docs.python.org/dev/py3k/whatsnew/… anuncia o plano de descontinuação a %partir do 3.1, mas isso nunca aconteceu.
Sven Marnach
8
O%-syntax ainda vive no Python 3 (não foi preterido no Python 3.2) #
Corey Goldberg
9
Apenas uma observação: o número em {}que eu posso ser eliminado.
chamar a
32

Eu desenvolvi o pacote interpy , que permite a interpolação de strings em Python .

Basta instalá-lo via pip install interpy. E então, adicione a linha # coding: interpyno início dos seus arquivos!

Exemplo:

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

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n#{name}."
Syrus Akbary Nieto
fonte
3
Isso parece realmente inseguro.
D33tah 12/12
@ d33tah: Não, desde que as strings sejam conhecidas em tempo de compilação.
Clément
28

A interpolação de string do Python é semelhante à printf () de C

Se você tentar:

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

A tag %sserá substituída pela namevariável Você deve dar uma olhada nas tags da função de impressão: http://docs.python.org/library/functions.html

Oleiade
fonte
11
como posso fazer isso com 2 variáveis?
Julio Marins
16
@JulioMarins Use uma tupla: print "First is %s, second is %s" % (var1, var2).
precisa saber é o seguinte
28

A interpolação de cadeias será incluída no Python 3.6, conforme especificado no PEP 498 . Você será capaz de fazer isso:

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

Note que eu odeio Bob Esponja, então escrever isso foi um pouco doloroso. :)

kirbyfan64sos
fonte
Thx para essa referência Bob Esponja (/ aversão): tenho que votar isso agora.
Javadba
4

Você também pode ter isso

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

Quan To
fonte
Não acredito que o OP pretendesse #ser impresso. Eles estão apenas usando a sintaxe Ruby.
Jaynp
Você está certo. Eu editei a resposta. Não estou familiarizado com Ruby, então pensei que o #personagem seria impresso.
Quan Até
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)

Uso:

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: desempenho pode ser um problema. Isso é útil para scripts locais, não para logs de produção.

Duplicado:

Paulo Check
fonte
2

Para Python antigo (testado no 2.4), a solução principal aponta o caminho. Você consegue fazer isso:

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()

E você recebe

d: 1 f: 1.1 s: s
Michael Fox
fonte