Utilisation de plusieurs arguments pour le formatage des chaînes en Python (par exemple, '% s…% s')

174

J'ai une chaîne qui ressemble '%s in %s'et je veux savoir comment séparer les arguments pour qu'ils soient deux% s différents. Mon esprit venant de Java est venu avec ceci:

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

Mais cela ne fonctionne pas alors à quoi cela ressemble-t-il en Python?

doyen
la source

Réponses:

191

La réponse de Mark Cidade est juste - vous devez fournir un tuple.

Cependant, à partir de Python 2.6, vous pouvez utiliser à la formatplace de %:

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

L'utilisation de %pour le formatage des chaînes n'est plus encouragée.

Cette méthode de mise en forme de chaîne est la nouvelle norme de Python 3.0 et doit être préférée à la mise en forme% décrite dans Opérations de mise en forme de chaîne dans le nouveau code.

Mark Byers
la source
5
À partir de Python 2.7, il peut également supprimer le numéro d'index, c'est-à-dire utiliser une '{} in {}'chaîne de format simple .
Cristian Ciupitu
121

Si vous utilisez plus d'un argument, il doit être dans un tuple (notez les parenthèses supplémentaires):

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

Comme le souligne EOL, la unicode()fonction suppose généralement le codage ascii par défaut, donc si vous avez des caractères non ASCII, il est plus sûr de passer explicitement le codage:

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

Et à partir de Python 3.0, il est préférable d'utiliser la str.format()syntaxe à la place:

'{0} in {1}'.format(unicode(self.author,'utf-8'),unicode(self.publication,'utf-8'))
Mark Cidade
la source
60

Sur un tuple / objet de mappage pour plusieurs arguments format

Ce qui suit est extrait de la documentation:

Étant donné format % values, les %spécifications de conversion en formatsont remplacées par zéro ou plusieurs éléments values. L'effet est similaire à l'utilisation sprintf()en langage C.

Si formatnécessite un seul argument, les valeurs peuvent être un seul objet non-tuple. Sinon, les valeurs doivent être un tuple avec exactement le nombre d'éléments spécifié par la formatchaîne , ou un seul objet de mappage (par exemple, un dictionnaire).

Références


Activé str.formatau lieu de%

Une alternative plus récente à l' %opérateur est d'utiliser str.format. Voici un extrait de la documentation:

str.format(*args, **kwargs)

Effectuez une opération de formatage de chaîne. La chaîne sur laquelle cette méthode est appelée peut contenir du texte littéral ou des champs de remplacement délimités par des accolades{} . Chaque champ de remplacement contient soit l'index numérique d'un argument de position, soit le nom d'un argument de mot-clé. Renvoie une copie de la chaîne dans laquelle chaque champ de remplacement est remplacé par la valeur de chaîne de l'argument correspondant.

Cette méthode est le nouveau standard de Python 3.0 et doit être préférée au %formatage .

Références


Exemples

Voici quelques exemples d'utilisation:

>>> '%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

Voir également

lubrifiants polygènes
la source
Je n'ai aucun moyen de tester cela (je ne connais pas beaucoup Python), mais les exemples semblent suggérer que quelque chose comme '{self.author} in {self.publication}'.format(self=self)devrait "fonctionner". Je ne suis tout simplement pas sûr de tout unicode.
polygenelubricants
1
Oui, vous pouvez en effet accéder aux attributs (et aussi aux index). Voir docs.python.org/library/string.html#formatstrings Donc, dans votre exemple, vous auriez pu utiliser {first[0]}pour obtenir l'initiale J.
Duncan
10

Vous devez simplement mettre les valeurs entre parenthèses:

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

Ici, pour le premier %sle unicode(self.author)sera placé. Et pour le second %s, le unicode(self.publication)sera utilisé.

Remarque: vous devriez privilégier string formattingla %notation. Plus d'infos ici

Bahadir Tasdemir
la source
Je ne peux pas croire que les gens suggèrent encore %splutôt alorsformat
user1767754
8

Il y a un problème important avec certaines des réponses publiées jusqu'à présent: unicode()décode à partir de l'encodage par défaut, qui est souvent ASCII; en fait, unicode()essaie de donner un «sens» aux octets qui lui sont donnés en les convertissant en caractères. Ainsi, le code suivant, qui est essentiellement ce qui est recommandé par les réponses précédentes, échoue sur ma machine:

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

donne:

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)

L'échec vient du fait qu'il authorne contient pas que des octets ASCII (c'est-à-dire avec des valeurs entre [0; 127]), et unicode()décode de l'ASCII par défaut (sur de nombreuses machines).

Une solution robuste est de donner explicitement l'encodage utilisé dans vos champs; en prenant UTF-8 comme exemple:

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

(ou sans l'initiale u, selon que vous voulez un résultat Unicode ou une chaîne d'octets).

À ce stade, vous pouvez envisager de faire en sorte que les champs authoret publicationsoient des chaînes Unicode, au lieu de les décoder lors du formatage.

Eric O Lebigot
la source
5

Pour python2, vous pouvez également le faire

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

ce qui est pratique si vous avez beaucoup d'arguments à substituer (surtout si vous faites de l'internationalisation)

Prise en charge de Python2.6 et versions ultérieures .format()

'{author} in {publication}'.format(author=self.author,
                                   publication=self.publication)
John La Rooy
la source
4

Vous pouvez également l'utiliser propre et simple (mais faux! Car vous devriez l'utiliser formatcomme Mark Byers l'a dit) en faisant:

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

Par souci d'exhaustivité, en python 3.6, des f-string sont introduites dans PEP-498 . Ces chaînes permettent de

incorporer des expressions dans des chaînes littérales, en utilisant une syntaxe minimale.

Cela signifierait que pour votre exemple, vous pourriez également utiliser:

f'{self.author} in {self.publication}'
westr
la source