Uso de múltiples argumentos para el formato de cadenas en Python (por ejemplo, '% s ...% s')


174

Tengo una cadena que se parece '%s in %s'y quiero saber cómo separar los argumentos para que sean dos% s diferentes. Mi mente proveniente de Java surgió con esto:

'%s in %s' % unicode(self.author),  unicode(self.publication)

Pero esto no funciona, ¿cómo se ve en Python?

Respuestas:


191

La respuesta de Mark Cidade es correcta: debe proporcionar una tupla.

Sin embargo, desde Python 2.6 en adelante puede usar en formatlugar de %:

'{0} in {1}'.format(unicode(self.author,'utf-8'),  unicode(self.publication,'utf-8'))

%Ya no se recomienda el uso de para formatear cadenas.

Este método de formateo de cadenas es el nuevo estándar en Python 3.0, y debe preferirse al formato% descrito en Operaciones de formateo de cadenas en código nuevo.


55
También comenzando con Python 2.7, puede soltar el número de índice, es decir, usar una '{} in {}'cadena de formato plano .
Cristian Ciupitu

121

Si está utilizando más de un argumento, debe estar en una tupla (tenga en cuenta los paréntesis adicionales):

'%s in %s' % (unicode(self.author),  unicode(self.publication))

Como señala EOL, la unicode()función generalmente asume la codificación ascii como predeterminada, por lo que si tiene caracteres no ASCII, es más seguro pasar explícitamente la codificación:

'%s in %s' % (unicode(self.author,'utf-8'),  unicode(self.publication('utf-8')))

Y a partir de Python 3.0, se prefiere usar la str.format()sintaxis en su lugar:

'{0} in {1}'.format(unicode(self.author,'utf-8'),unicode(self.publication,'utf-8'))

60

En un objeto tuple / mapping para argumento múltiple format

Lo siguiente es un extracto de la documentación:

Dado format % values, %las especificaciones de conversión en formatse reemplazan con cero o más elementos de values. El efecto es similar al uso sprintf()en el lenguaje C.

Si formatrequiere un único argumento, los valores pueden ser un único objeto sin tupla. De lo contrario, los valores deben ser una tupla con exactamente el número de elementos especificados por la formatcadena , o un solo objeto de mapeo (por ejemplo, un diccionario).

Referencias


En str.formatlugar de%

Una alternativa más nueva al %operador es usar str.format. Aquí hay un extracto de la documentación:

str.format(*args, **kwargs)

Realizar una operación de formateo de cadena. La cadena en la que se llama a este método puede contener texto literal o campos de reemplazo delimitados por llaves {}. Cada campo de reemplazo contiene el índice numérico de un argumento posicional o el nombre de un argumento de palabra clave. Devuelve una copia de la cadena donde cada campo de reemplazo se reemplaza con el valor de cadena del argumento correspondiente.

Este método es el nuevo estándar en Python 3.0, y debería preferirse al %formateo .

Referencias


Ejemplos

Aquí hay algunos ejemplos de uso:

>>> '%s for %s' % ("tit", "tat")
tit for tat

>>> '{} and {}'.format("chicken", "waffles")
chicken and waffles

>>> '%(last)s, %(first)s %(last)s' % {'first': "James", 'last': "Bond"}
Bond, James Bond

>>> '{last}, {first} {last}'.format(first="James", last="Bond")
Bond, James Bond

Ver también


No tengo forma de probar esto (no conozco tanto a Python), pero los ejemplos parecen sugerir que algo como '{self.author} in {self.publication}'.format(self=self)"debería funcionar". Simplemente no estoy seguro de todo el unicodeasunto.
Polygenelubricants

1
Sí, puede acceder a los atributos (y también a los índices). Consulte docs.python.org/library/string.html#formatstrings. Entonces, en su ejemplo, podría haber utilizado {first[0]}para obtener la inicial J.
Duncan

10

Solo debes poner los valores entre paréntesis:

'%s in %s' % (unicode(self.author),  unicode(self.publication))

Aquí, por primera %sel unicode(self.author)será colocado. Y para el segundo %s, unicode(self.publication)se utilizará el.

Nota: debe favorecer string formattingsobre la %notación. Más información aquí.


No puedo creer que la gente todavía sugiera en %slugar de esoformat
user1767754

8

Hay un problema importante con algunas de las respuestas publicadas hasta ahora: unicode()decodifica desde la codificación predeterminada, que a menudo es ASCII; de hecho, unicode()trata de dar "sentido" a los bytes que se le dan al convertirlos en caracteres. Por lo tanto, el siguiente código, que es esencialmente lo que recomiendan las respuestas anteriores, falla en mi máquina:

# -*- coding: utf-8 -*-
author = 'éric'
print '{0}'.format(unicode(author))

da:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print '{0}'.format(unicode(author))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

La falla proviene del hecho de que authorno contiene solo bytes ASCII (es decir, con valores en [0; 127]), y unicode()decodifica desde ASCII por defecto (en muchas máquinas).

Una solución robusta es dar explícitamente la codificación utilizada en sus campos; tomando UTF-8 como ejemplo:

u'{0} in {1}'.format(unicode(self.author, 'utf-8'), unicode(self.publication, 'utf-8'))

(o sin la inicial u, dependiendo de si desea un resultado Unicode o una cadena de bytes).

En este punto, uno podría considerar tener los campos authory publicationcomo cadenas Unicode, en lugar de decodificarlos durante el formateo.


5

Para python2 también puedes hacer esto

'%(author)s in %(publication)s'%{'author':unicode(self.author),
                                  'publication':unicode(self.publication)}

lo cual es útil si tiene muchos argumentos para sustituir (particularmente si está haciendo internacionalización)

Python2.6 en adelante soporta .format()

'{author} in {publication}'.format(author=self.author,
                                   publication=self.publication)

4

También puede usarlo limpio y simple (¡pero incorrecto! Porque debe usarlo formatcomo dijo Mark Byers) haciendo:

print 'This is my %s formatted with %d arguments' % ('string', 2)

3

Para completar, en Python 3.6 se introducen f-string en PEP-498 . Estas cadenas hacen posible

incrustar expresiones dentro de literales de cadena, utilizando una sintaxis mínima.

Eso significaría que para su ejemplo también podría usar:

f'{self.author} in {self.publication}'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.