Uso de múltiples argumentos para el formato de cadena en Python (p. ej., ‘%s … %s’)

5 minutos de lectura

avatar de usuario
Decano

Tengo una cadena que parece '%s in %s' y quiero saber como separar los argumentos para que sean dos %s diferentes. A mi mente que viene de Java se le ocurrió esto:

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

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

avatar de usuario
marca byers

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

Sin embargo, desde Python 2.6 en adelante puedes usar format en vez de %:

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

Uso de % para dar formato a las cadenas ya no se recomienda.

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

  • También a partir de Python 2.7, puede eliminar el número de índice, es decir, usar un '{} in {}' cadena de formato.

    – Cristian Ciupitu

    31 de mayo de 2015 a las 8:11

avatar de usuario
marca ciudad

Si usa 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() La función generalmente asume la codificación ASCII como predeterminada, por lo que si tiene caracteres que no son 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 el str.format() sintaxis en su lugar:

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

avatar de usuario
poligenelubricantes

En una tupla/objeto de mapeo para múltiples argumentos format

El siguiente es un extracto de la documentación:

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

Si format requiere un solo argumento, los valores pueden ser un solo objeto que no sea una tupla. De lo contrario, los valores deben ser una tupla con exactamente el número de elementos especificado por el format cuerda, o un solo objeto de mapeo (por ejemplo, un diccionario).

Referencias


En str.format en vez de %

Una nueva alternativa a % el operador es usar str.format. He aquí un extracto de la documentación:

str.format(*args, **kwargs)

Realice una operación de formato 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 debe preferirse a % formato.

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 sé mucho de Python), pero los ejemplos parecen sugerir que algo como '{self.author} in {self.publication}'.format(self=self) Deberia trabajar”. No estoy seguro del todo unicode cosa.

    – poligenolubricantes

    3 de agosto de 2010 a las 10:08


  • Sí, de hecho puede acceder a los atributos (y también a los índices). Ver docs.python.org/library/string.html#formatstrings Así que en tu ejemplo podrías haber usado {first[0]} para obtener la inicial J.

    – Duncan

    3 de agosto de 2010 a las 12:43

avatar de usuario
Bahadir Tasdemir

Solo debes poner los valores entre paréntesis:

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

Aquí, por primera %s la unicode(self.author) será puesto. y por el segundo %sla unicode(self.publication) se utilizará.

Nota: Debe favorecer string formatting sobre el % Notación. Más información aquí

avatar de usuario
Eric O Lebigot

Hay un problema importante con algunas de las respuestas publicadas hasta ahora: unicode() decodifica a partir de la codificación predeterminada, que suele ser ASCII; De hecho, unicode() intenta dar “sentido” a los bytes que se le dan convirtiéndolos 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)

El fracaso proviene del hecho de que author no contiene sólo bytes ASCII (es decir, con valores en [0; 127]), y unicode() decodifica de 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 udependiendo de si desea un resultado Unicode o una cadena de bytes).

En este punto, uno podría querer considerar tener la author y publication campos sean cadenas Unicode, en lugar de decodificarlos durante el formateo.

avatar de usuario
Juan La Rooy

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 admite .format()

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

avatar de usuario
oeste

Para completar, en python 3.6 f-string se introducen en PEP-498. Estas cadenas permiten

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

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

f'{self.author} in {self.publication}'

¿Ha sido útil esta solución?