Formatação de string denominada parâmetros?

135

Eu sei que é uma pergunta muito simples, mas não tenho idéia de como pesquisar no Google.

Como eu posso fazer

print '<a href="%s">%s</a>' % (my_url)

Então isso my_urlé usado duas vezes? Eu suponho que tenho que "nomear" o %se usar um dict nos parâmetros, mas não tenho certeza da sintaxe adequada?


apenas para sua informação, sei que posso usar my_urlduas vezes nos parâmetros, mas esse não é o ponto :)

mpen
fonte
O título da pergunta é um pouco enganador. Isso não tem nada a ver com a instrução print, apenas com o funcionamento da interpolação de strings.
Greg Bola
Quando você não tem idéia de como pesquisar no Google, acesse aqui para usar a pesquisa: python.org/doc . É melhor que o Google por um motivo importante.
S.Lott
@ S. Lott que é realmente útil / s
MPEN

Respostas:

80

No Python 2.6+ e Python 3, você pode optar por usar o método de formatação de string mais recente.

print('<a href="{0}">{0}</a>'.format(my_url))

o que evita que você repita o argumento, ou

print('<a href="{url}">{url}</a>'.format(url=my_url))

se você quiser parâmetros nomeados.

print('<a href="{}">{}</a>'.format(my_url, my_url))

que é estritamente posicional e vem apenas com a ressalva de que os argumentos format () seguem as regras do Python em que args não nomeados devem vir primeiro, seguidos por argumentos nomeados, seguidos por * args (uma sequência como lista ou tupla) e depois * kwargs (um dict digitado com strings se você souber o que é bom para você). Os pontos de interpolação são determinados primeiro substituindo os valores nomeados em seus rótulos e depois posicionais do que resta. Então, você também pode fazer isso ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, my_url, not_my_url=her_url))

Mas não isso ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, not_my_url=her_url, my_url))
Greg Ball
fonte
É bom ver a mudança de influência a partir ++ a #
cod3monk3y
3
O método acima não é para formatação de string nomeada , porém, é uma formatação de string posicional. Portanto, isso realmente não responde à pergunta.
jaapz
O "literal {arg1}".format(arg1="arg!")formato nomeado funciona com o Python 3.5, enquanto o terser f"literal {arg1}"é uma inovação mais recente no Python 3.6 ou AFAIK.
MarkHu
218
print '<a href="%(url)s">%(url)s</a>' % {'url': my_url}
Ignacio Vazquez-Abrams
fonte
3
Eu prefiro criar o dict com kwargs:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar 14/10
11
Eu me pergunto por que você prefere esse schmlamar? Eu não teria prontamente conhecido o que isso significava, em comparação aos da declaração normal de um dict que os usos OP ...
GreenAsJade
1
A documentação não diz quando isso foi introduzido, portanto provavelmente está em todas as versões do Python 2.
Evgeni Sergeev
2
Use format (), se puder, ele funciona melhor e em mais lugares. Use% se você DEVE.
Uchuugaka
39

Solução em Python 3.6+

O Python 3.6 introduz formatação literal de string , para que você possa formatar os parâmetros nomeados sem repetir nenhum dos parâmetros nomeados fora da string:

print(f'<a href="{my_url:s}">{my_url:s}</a>')

Isso avaliará my_url, portanto, se não estiver definido, você receberá um NameError. De fato, em vez de my_url, você pode escrever uma expressão Python arbitrária, desde que seja avaliada como uma string (por causa do :scódigo de formatação). Se você deseja uma representação de sequência para o resultado de uma expressão que pode não ser uma sequência, substitua :spor !s, assim como na formatação regular pré-literal.

Para detalhes sobre a formatação literal de cadeias, consulte PEP 498 , onde foi introduzido pela primeira vez.

gerrit
fonte
1
Esse PEP parece não cobrir todos os formatadores; Eu acho que eles são o mesmo que str.format que está documentado aqui: docs.python.org/3.4/library/string.html#formatstrings
mpen
6

Você será viciado em sintaxe.

Também em C # 6.0, os desenvolvedores do EcmaScript também familiarizam essa sintaxe.

In [1]: print '{firstname} {lastname}'.format(firstname='Mehmet', lastname='Ağa')
Mehmet Ağa

In [2]: print '{firstname} {lastname}'.format(**dict(firstname='Mehmet', lastname='Ağa'))
Mehmet Ağa
guneysus
fonte
5

Para criar páginas HTML, você deseja usar um mecanismo de modelagem, não uma simples interpolação de cadeias.

Mike Graham
fonte
2
O mecanismo de modelagem do Django também pode ser a ferramenta ideal para os e-mails que você está enviando.
Mike Graham
6
O que está impedindo você de usar um modelo do Django para gerar um corpo de email com seu render()método? Nada diz que você precisa alimentar a saída do modelo HttpResponse(). O Django é embaraçosamente versátil.
Mike DeSimone
1
@ Mike: Eu pensei que o Django também poderia ter uma solução para isso, mas ainda não a encontrei: p Provavelmente vou mover meus e-mails para modelos! Obrigado. Talvez eu esteja atrasado, mas achei bastante rígido em algumas áreas.
MPEN
2
Pessoas aleatórias do @ que leram esses comentários: encontraram mais detalhes sobre como fazer isso aqui rossp.org/blog/2006/jul/11/sending-e-mails-templates
mpen
1
Para comentar as perguntas, você deseja usar comentários, não respostas.
suriv
2

Assim como a maneira do dicionário, pode ser útil conhecer o seguinte formato:

print '<a href="%s">%s</a>' % (my_url, my_url)

Aqui é um pouco redundante, e a maneira do dicionário certamente é menos propensa a erros ao modificar o código, mas ainda é possível usar tuplas para várias inserções. O primeiro %ssubstitui o primeiro elemento da tupla, o segundo %ssubstitui o segundo elemento da tupla e assim por diante para cada elemento da tupla.

Ponkadoodle
fonte
Eu acabei de denunciar um cara por sugerir isso :) Ele excluiu sua postagem. Eu me sinto meio mal agora. Sim, eu sei que posso fazer isso, mas não era o que eu estava procurando. Como você disse, é redundante e, my_urlna verdade , é uma chamada de função que não quero que seja avaliada duas vezes. Duas vezes não é tão ruim, mas poderia facilmente ter sido 20 vezes :)
MPEN
5
Pensei em manter o meu, para o caso de ajudar alguém. Bem, o caminho do dicionário é provavelmente o melhor caminho a percorrer. Mas para redundância, (get_my_url(), )*20apenas chama a função uma vez e a duplica 20 vezes.
Ponkadoodle