Cadena de formato de los parámetros con nombre?

135

Sé que es una pregunta muy simple, pero no tengo idea de cómo buscarla en Google.

Como lo puedo hacer

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

Entonces, ¿eso my_urlse usa dos veces? Supongo que tengo que "nombrar" el %sy luego usar un dict en los parámetros, pero no estoy seguro de la sintaxis adecuada.


solo para tu información, sé que puedo usar my_urldos veces en los parámetros, pero ese no es el punto :)

mpen
fuente
El título de la pregunta es un poco engañoso. Esto no tiene nada que ver con la declaración de impresión, solo con cómo funciona la interpolación de cadenas.
Greg Ball
Cuando no tenga idea de cómo buscarlo en Google, vaya aquí para usar la búsqueda: python.org/doc . Es mejor que Google por una razón importante.
S.Lott
@ S.Lott Eso es realmente útil / s
mpen

Respuestas:

80

En Python 2.6+ y Python 3, puede optar por utilizar el método de formato de cadena más nuevo.

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

que te salva de repetir el argumento, o

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

si quieres parámetros con nombre.

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

que es estrictamente posicional, y solo viene con la advertencia de que los argumentos de formato () siguen las reglas de Python donde los argumentos sin nombre deben venir primero, seguidos de los argumentos con nombre, seguidos de * args (una secuencia como lista o tupla) y luego * kwargs (un dict tecleado con cuerdas si sabes lo que es bueno para ti). Los puntos de interpolación se determinan primero sustituyendo los valores nombrados en sus etiquetas, y luego posicionales de lo que queda. Entonces, también puedes hacer esto ...

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

Pero no esto ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, not_my_url=her_url, my_url))
Greg Ball
fuente
Es agradable ver que la influencia cambia de ++ a #
cod3monk3y
3
Sin embargo, el método anterior no es para el formato de cadena con nombre , este es el formato de cadena posicional. Entonces esto realmente no responde la pregunta.
jaapz
El "literal {arg1}".format(arg1="arg!")formato con nombre funciona con Python 3.5, mientras que el terser f"literal {arg1}"es una innovación más reciente en Python 3.6 o más reciente, AFAIK.
MarkHu
218
print '<a href="%(url)s">%(url)s</a>' % {'url': my_url}
Ignacio Vazquez-Abrams
fuente
3
Prefiero crear el dict con kwargs:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar
11
Me pregunto por qué prefieres ese schmlamar? No habría sabido fácilmente qué significaba eso, comparado con la declaración normal de un dict que el OP utiliza ...
GreenAsJade
1
La documentación no dice cuándo se introdujo esto, por lo que probablemente esté en todas las versiones de Python 2.
Evgeni Sergeev
2
Utilice format () si puede, funciona mejor y en más lugares. Use% si DEBE.
uchuugaka
39

Solución en Python 3.6+

Python 3.6 introduce el formato de cadena literal , para que pueda formatear los parámetros con nombre sin repetir ninguno de sus parámetros con nombre fuera de la cadena:

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

Esto evaluará my_url, por lo que si no está definido obtendrá un NameError. De hecho, en lugar de my_url, puede escribir una expresión arbitraria de Python, siempre que se evalúe como una cadena (debido al :scódigo de formato). Si desea una representación de cadena para el resultado de una expresión que podría no ser una cadena, reemplácela :spor !s, al igual que con el formato de cadena regular y pre-literal.

Para obtener detalles sobre el formato de cadena literal, consulte PEP 498 , donde se introdujo por primera vez.

gerrit
fuente
1
Ese PEP no parece cubrir todos los formateadores; Creo que son lo mismo que str.format, que se documenta aquí: docs.python.org/3.4/library/string.html#formatstrings
mpen
6

Serás adicto a la sintaxis.

También C # 6.0, los desarrolladores de EcmaScript también tienen esta sintaxis más familiar.

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
fuente
5

Para crear páginas HTML, desea utilizar un motor de plantillas, no una simple interpolación de cadenas.

Mike Graham
fuente
2
El motor de plantillas de Django también puede ser la herramienta ideal para los correos electrónicos que está haciendo.
Mike Graham
66
¿Qué le impide usar una plantilla de Django para generar un cuerpo de correo electrónico con su render()método? Nada dice que tiene que alimentar la salida de la plantilla HttpResponse(). Django es vergonzosamente versátil.
Mike DeSimone
1
@ Mike: pensé que Django podría tener una solución para esto también, pero aún no la había encontrado: p ¡Entonces probablemente moveré mis correos electrónicos a plantillas! Gracias. Tal vez estoy 'empañado, pero he encontrado que es bastante rígido en algunas áreas.
mpen
2
@ personas aleatorias que leen estos comentarios: encontraron más detalles sobre cómo hacerlo aquí rossp.org/blog/2006/jul/11/sending-e-mails-templates
mpen
1
Para comentar preguntas, desea usar comentarios, no respuestas.
Suriv
2

Además de la forma del diccionario, puede ser útil conocer el siguiente formato:

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

Aquí es un poco redundante, y la forma del diccionario es ciertamente menos propensa a errores al modificar el código, pero aún es posible usar tuplas para múltiples inserciones. El primero %sse sustituye por el primer elemento en la tupla, el segundo %sse sustituye por el segundo elemento en la tupla, y así sucesivamente por cada elemento en la tupla.

Ponkadoodle
fuente
Acabo de decirle a un chico que sugirió esto :) Eliminó su publicación. Me siento un poco mal ahora. Sí, sé que puedo hacer esto, pero no era lo que estaba buscando. Como dijiste, es redundante y en my_urlrealidad es una llamada de función que no quiero que me evalúen dos veces. Dos veces no es tan malo, pero podría haber sido fácilmente 20 veces :)
mpen
55
Pensé que me quedaría con el mío, en caso de que ayude a alguien más. Bueno, el camino del diccionario es probablemente el mejor camino a seguir. Pero por redundancia, (get_my_url(), )*20solo llama a la función una vez y la duplica 20 veces.
Ponkadoodle