web-dev-qa-db-fra.com

Utilisation de plusieurs arguments pour le formatage de chaîne dans Python (par exemple, '% s ...% s')

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

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

Mais cela ne fonctionne pas, comment cela se passe-t-il en Python?

148
Dean

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

Toutefois, à partir de Python 2.6, vous pouvez utiliser format au lieu de %:

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

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

Cette méthode de formatage de chaîne est la nouvelle norme dans Python 3.0 et doit être préférée au% de formatage décrit dans Opérations de formatage de chaîne dans le nouveau code.

170
Mark Byers

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 fonction unicode() considère généralement le codage ascii par défaut. Par conséquent, si vous utilisez des caractères non-ASCII, il est plus sûr de le transmettre explicitement:

'%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 syntaxe str.format() :

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

Sur un tuple/un objet de mappage pour plusieurs arguments format

Ce qui suit est extrait de la documentation:

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

Si format né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 chaîne format string , ou un seul objet de mappage (par exemple, un dictionnaire).

Références


Sur str.format au lieu de %

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

str.format(*args, **kwargs)

Effectuer 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é. Retourne une copie de la chaîne où chaque champ de remplacement est remplacé par la valeur de chaîne de l'argument correspondant.

Cette méthode est la nouvelle norme dans Python 3.0 et devrait être préférée à % 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

54
polygenelubricants

Vous devez simplement mettre les valeurs entre parenthèses:

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

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

Remarque: Vous devez privilégier string formatting par rapport à la notation %. Plus d'infos ici

10
Bahadir Tasdemir

Certaines des réponses publiées à ce jour posent un problème important: unicode() décode à partir du codage par défaut, qui est souvent ASCII; En fait, unicode() essaie de "comprendre" les octets qui lui sont attribué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 que author ne contient pas seulement ASCII octets (c'est-à-dire avec des valeurs dans [0; 127]) et que unicode() décode à partir de ASCII. _ par défaut (sur de nombreuses machines).

Une solution robuste consiste à donner explicitement le codage 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, on peut envisager de faire en sorte que les champs author et publication soient des chaînes Unicode, au lieu de les décoder lors du formatage.

8
Eric O Lebigot

Pour python2, vous pouvez aussi 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 (en particulier si vous effectuez une internationalisation)

Python2.6 prend en charge .format()

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

Vous pouvez aussi l’utiliser propre et simple (mais faux! Parce que vous devriez utiliser format comme Mark Byers l’a dit) en faisant:

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