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.


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


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

@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!")

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}."

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


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


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


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:


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.