Formatage de chaîne en Python 3

114

Je fais cela en Python 2:

"(%d goals, $%d)" % (self.goals, self.penalties)

Quelle est la version Python 3 de ceci?

J'ai essayé de rechercher des exemples en ligne mais j'ai continué à obtenir des versions de Python 2.

JoseBazBaz
la source
Ce n'était pas obsolète; votre code fonctionne bien. En savoir plus ici .
jackcogdill
32
Remarque pour le lecteur occasionnel: le signe dollar n'a pas de signification particulière. C'est juste un signe dollar ici. (Merci Martijn Pieters)
kevinarpe
1
pyformat.info et python-course.eu/python3_formatted_output.php (Not my sites)
Christophe Roussy
1
Le signe dollar rendait cela très déroutant.
cchamberlain

Réponses:

173

Voici la documentation sur la «nouvelle» syntaxe de format. Un exemple serait:

"({:d} goals, ${:d})".format(self.goals, self.penalties)

Si les deux goalset penaltiessont des entiers (c'est-à-dire que leur format par défaut est correct), il peut être raccourci à:

"({} goals, ${})".format(self.goals, self.penalties)

Et comme les paramètres sont des champs de self, il existe également un moyen de le faire en utilisant un seul argument deux fois (comme @Burhan Khalid l'a noté dans les commentaires):

"({0.goals} goals, ${0.penalties})".format(self)

Expliquer:

  • {} signifie juste le prochain argument de position, avec le format par défaut;
  • {0}signifie l'argument avec index 0, avec le format par défaut;
  • {:d} est le prochain argument de position, au format entier décimal;
  • {0:d}est l'argument avec index 0, au format entier décimal.

Il y a beaucoup d'autres choses que vous pouvez faire lors de la sélection d'un argument (en utilisant des arguments nommés au lieu d'arguments positionnels, en accédant aux champs, etc.) et de nombreuses options de format également (remplir le nombre, utiliser des séparateurs de milliers, afficher le signe ou non, etc.). Quelques autres exemples:

"({goals} goals, ${penalties})".format(goals=2, penalties=4)
"({goals} goals, ${penalties})".format(**self.__dict__)

"first goal: {0.goal_list[0]}".format(self)
"second goal: {.goal_list[1]}".format(self)

"conversion rate: {:.2f}".format(self.goals / self.shots) # '0.20'
"conversion rate: {:.2%}".format(self.goals / self.shots) # '20.45%'
"conversion rate: {:.0%}".format(self.goals / self.shots) # '20%'

"self: {!s}".format(self) # 'Player: Bob'
"self: {!r}".format(self) # '<__main__.Player instance at 0x00BF7260>'

"games: {:>3}".format(player1.games)  # 'games: 123'
"games: {:>3}".format(player2.games)  # 'games:   4'
"games: {:0>3}".format(player2.games) # 'games: 004'

Remarque: comme d'autres l'ont souligné, le nouveau format ne remplace pas l'ancien, les deux sont également disponibles à la fois dans Python 3 et dans les versions plus récentes de Python 2. Certains peuvent dire que c'est une question de préférence, mais à mon humble avis, le plus récent est beaucoup plus expressif que l'ancien et devrait être utilisé chaque fois que vous écrivez un nouveau code (à moins qu'il ne cible des environnements plus anciens, bien sûr).

mgibsonbr
la source
9
Vous pouvez aussi faire"({0.goals} goals, ${0.penalties})".format(self)
Burhan Khalid
Vous devez prendre le '%' en dehors des accolades, par exemple {: .2f%} -> {: .2f}%
SuperElectric
@SuperElectric - vous dire, dans cette ligne: "conversion rate: {:.2%}".format(self.goals / self.shots)? Fonctionne bien pour moi tel quel ... (Python 3.4) Notez qu'il n'y a pas fdedans, je demande de formater en pourcentage, pas en nombre à virgule flottante.
mgibsonbr
Vous avez raison; cela semble fonctionner en Python 3.4, donc c'est bien puisque l'OP posait des questions sur Python3. Je viens de trouver que cela ne fonctionnait pas avec python 2.7.6. "{:.2f}%".format(float_num)fonctionne bien pour les deux.
SuperElectric
1
@JohnSchmitt Oui, cet exemple était censé donner exactement le même résultat que le code donné dans la question. Le $n'a pas de signification particulière ici, ni dans l'ancienne syntaxe de format ni dans le nouveau, donc devrait être présent dans la chaîne générée, inchangé.
mgibsonbr
67

Python 3.6 prend désormais en charge l'interpolation de chaîne littérale abrégée avec PEP 498 . Pour votre cas d'utilisation, la nouvelle syntaxe est simplement:

f"({self.goals} goals, ${self.penalties})"

Ceci est similaire à la .formatnorme précédente , mais permet de faire facilement des choses comme :

>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal('12.34567')
>>> f'result: {value:{width}.{precision}}'
'result:      12.35'
JDong
la source
12

Cette ligne fonctionne telle quelle dans Python 3.

>>> sys.version
'3.2 (r32:88445, Oct 20 2012, 14:09:29) \n[GCC 4.5.2]'
>>> "(%d goals, $%d)" % (self.goals, self.penalties)
'(1 goals, $2)'
Mark Reed
la source
D'ACCORD. COOL. Après avoir posté la question, j'ai poursuivi ma recherche et j'ai trouvé que nous devions faire {% d} au lieu de seulement% d. Est-ce correct également? Ou la méthode Python2 est-elle la seule façon de le faire?
JoseBazBaz
2
Python 3 introduit une nouvelle syntaxe - ce sont les accolades - mais vous n'êtes pas obligé de l'utiliser. Vous pouvez utiliser l'ancien ou le nouveau. Mais ils sont différents; si vous utilisez des boucles, vous n'utilisez pas de signes de pourcentage.
Mark Reed
2

J'aime cette approche

my_hash = {}
my_hash["goals"] = 3 #to show number
my_hash["penalties"] = "5" #to show string
print("I scored %(goals)d goals and took %(penalties)s penalties" % my_hash)

Notez le d et le s annexés aux crochets respectivement.

la sortie sera:

I scored 3 goals and took 5 penalties
fullstacklife
la source