Como faço para criar uma string Python multilinha com variáveis ​​embutidas?

94

Estou procurando uma maneira limpa de usar variáveis ​​dentro de uma string Python multilinha. Digamos que eu queira fazer o seguinte:

string1 = go
string2 = now
string3 = great

"""
I will $string1 there
I will go $string2
$string3
"""

Estou procurando ver se há algo semelhante $em Perl para indicar uma variável na sintaxe Python.

Se não, qual é a maneira mais limpa de criar uma string multilinha com variáveis?

evolução
fonte

Respostas:

155

A maneira comum é a format()função:

>>> s = "This is an {example} with {vars}".format(vars="variables", example="example")
>>> s
'This is an example with variables'

Ele funciona bem com uma string de formato de várias linhas:

>>> s = '''\
... This is a {length} example.
... Here is a {ordinal} line.\
... '''.format(length='multi-line', ordinal='second')
>>> print(s)
This is a multi-line example.
Here is a second line.

Você também pode passar um dicionário com variáveis:

>>> d = { 'vars': "variables", 'example': "example" }
>>> s = "This is an {example} with {vars}"
>>> s.format(**d)
'This is an example with variables'

A coisa mais próxima do que você perguntou (em termos de sintaxe) são strings de modelo . Por exemplo:

>>> from string import Template
>>> t = Template("This is an $example with $vars")
>>> t.substitute({ 'example': "example", 'vars': "variables"})
'This is an example with variables'

Devo acrescentar, porém, que a format()função é mais comum porque está prontamente disponível e não requer uma linha de importação.

Simeon Visser
fonte
2
Poderia usar vars()ou locals()como o dicionário em questão
Ismail Badawi
2
@isbadawi Explícito é melhor do que implícito. É melhor passar apenas as variáveis ​​de que você precisa. Se você não sabe de qual precisa, porque a string é fornecida pelo usuário, as "variáveis" devem ser itens de dictqualquer maneira.
agf
A segunda solução é a IMO mais limpa. O dicionário junto com o nome da variável claro do dicionário dentro do sting multilinha. Eu estarei usando este método. Obrigado. Muitas respostas ótimas abaixo também, mas isso foi perfeito.
evolução em
@SimeonVisser, "string" .format (...) não é válido em versões Python legadas (por exemplo, 2.4)
Oz123
Se estiver usando colchetes, é necessário escapar como {{this}}.
Jonny
52

NOTA : A maneira recomendada de fazer a formatação de strings em Python é usar format(), conforme descrito na resposta aceita . Estou preservando esta resposta como um exemplo da sintaxe de estilo C que também é compatível.

# NOTE: format() is a better choice!
string1 = "go"
string2 = "now"
string3 = "great"

s = """
I will %s there
I will go %s
%s
""" % (string1, string2, string3)

print(s)

Algumas leituras:

David Cain
fonte
2
Isso não é realmente o mesmo porque o OP deseja parâmetros nomeados, não posicionais.
Ismail Badawi
1
Ainda é uma boa solução e para uma interpolação multilinha é mais direta. Você não tem que importar nada e usa interpolação regular do Python.
desflores em
4
" Você provavelmente poderia ter respondido esta aqui pesquisando um pouco no Google ", o que implica que não encontramos esta postagem após pesquisar no Google ...
Stevoisiak
30

Você pode usar as strings f do Python 3.6 para variáveis ​​dentro de strings de várias linhas ou longas de uma linha. Você pode especificar manualmente os caracteres de nova linha usando \n.

Variáveis ​​em uma string multilinha

string1 = "go"
string2 = "now"
string3 = "great"

multiline_string = (f"I will {string1} there\n"
                    f"I will go {string2}.\n"
                    f"{string3}.")

print(multiline_string)

Eu irei lá
eu irei agora
ótimo

Variáveis ​​em uma longa string de linha única

string1 = "go"
string2 = "now"
string3 = "great"

singleline_string = (f"I will {string1} there. "
                     f"I will go {string2}. "
                     f"{string3}.")

print(singleline_string)

Eu vou lá. Eu vou agora. ótimo.


Como alternativa, você também pode criar uma string F multilinha com aspas triplas.

multiline_string = f"""I will {string1} there.
I will go {string2}.
{string3}."""
Stevoisiak
fonte
Isso mantém seu código-fonte com uma boa aparência, e no pré-Python3.6 você pode obter o mesmo efeito apenas fazendo isso (conjunto extra de parênteses e usando +para concatenar): stackoverflow.com/a/54564926/4561887
Gabriel Staples
A citação tripla é amplamente preferida. Você deve apresentar esse formulário primeiro.
jpmc26
@ jpmc26 Apresentei primeiro o estilo de parênteses com base nas diretrizes do PEP 8 para indentação de código . Por que a citação tripla seria preferida?
Stevoisiak
10

Isso é o que você quer:

>>> string1 = "go"
>>> string2 = "now"
>>> string3 = "great"
>>> mystring = """
... I will {string1} there
... I will go {string2}
... {string3}
... """
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, 'string3': 'great', '__package__': None, 'mystring': "\nI will {string1} there\nI will go {string2}\n{string3}\n", '__name__': '__main__', 'string2': 'now', '__doc__': None, 'string1': 'go'}
>>> print(mystring.format(**locals()))

I will go there
I will go now
great
Havok
fonte
Observe que as aspas triplas """preservam as novas linhas, o que significa que há uma nova linha extra antes e depoismystring
Stevoisiak
Você pode usar .strip(), .rstrip()ou .lstrip()ou usar uma folga dentro das aspas triplas para evitar a criação de uma nova linha. mystring = "" "\ ABC \" ""
Havok
6

Um dicionário pode ser passado para format(), cada nome de chave se tornará uma variável para cada valor associado.

dict = {'string1': 'go',
        'string2': 'now',
        'string3': 'great'}

multiline_string = '''I'm will {string1} there
I will go {string2}
{string3}'''.format(**dict)

print(multiline_string)


Além disso, uma lista pode ser passada para format(), o número do índice de cada valor será usado como variável neste caso.

list = ['go',
        'now',
        'great']

multiline_string = '''I'm will {0} there
I will go {1}
{2}'''.format(*list)

print(multiline_string)


Ambas as soluções acima produzirão o mesmo:

Eu irei lá
Eu irei agora
ótimo

jesterjunk
fonte
0

Se alguém veio aqui do cliente python-graphql procurando uma solução para passar um objeto como variável, aqui está o que usei:

query = """
{{
  pairs(block: {block} first: 200, orderBy: trackedReserveETH, orderDirection: desc) {{
    id
    txCount
    reserveUSD
    trackedReserveETH
    volumeUSD
  }}
}}
""".format(block=''.join(['{number: ', str(block), '}']))

 query = gql(query)

Certifique-se de escapar de todas as chaves como eu fiz: "{{", "}}"

Radu Ciobanu
fonte
0

strings f , também chamadas de “literais de string formatadas”, são literais de string que têm um fno início; e chaves contendo expressões que serão substituídas por seus valores.

strings f são avaliadas em tempo de execução.

Portanto, seu código pode ser reescrito como:

string1="go"
string2="now"
string3="great"
print(f"""
I will {string1} there
I will go {string2}
{string3}
""")

E isso vai avaliar para:

I will go there
I will go now
great

Você pode aprender mais sobre isso aqui .

Anshika Singh
fonte