Використання декількох аргументів для форматування рядків у Python (наприклад, '% s…% s')


174

У мене є рядок, який виглядає так, '%s in %s'і я хочу знати, як розділити аргументи, щоб вони були двома різними% s. Мій розум, що походить з Java, придумав таке:

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

Але це не працює, так як це виглядає в Python?

Відповіді:


191

Відповідь Марка Сідаде правильна - вам потрібно поставити кортеж.

Однак з Python 2.6 ви можете використовувати formatзамість %:

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

Використання %для форматування рядків більше не рекомендується.

Цей спосіб форматування рядків є новим стандартом в Python 3.0, і його слід віддавати перевагу формату%, описаному в String Formatting Operations в новому коді.


5
Також починаючи з Python 2.7, він може скидати індексний номер, тобто використовувати '{} in {}'рядок простого формату.
Крістіан Цюпіту

121

Якщо ви використовуєте більше одного аргументу, він повинен бути в кордоні (зверніть увагу на додаткові дужки):

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

Як зазначає EOL, unicode()функція зазвичай передбачає кодування ascii за замовчуванням, тому якщо у вас є символи, що не належать до ASCII, безпечніше явно передавати кодування:

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

А що стосується Python 3.0, то краще використовувати str.format()синтаксис:

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

60

На об'єкт кортежу / відображення для декількох аргументів format

Далі є витяг із документації:

З огляду на те format % values, що %специфікації перетворення в formatзамінені на нуль або більше елементів values. Ефект схожий на використання sprintf()в мові С.

Якщо formatпотрібен один аргумент, значення можуть бути одним об'єктом, що не змінюється. В іншому випадку значення повинні бути кортежем із точно кількістю елементів, визначених formatрядком , або одним об'єктом відображення (наприклад, словником).

Список літератури


На str.formatзамість%

Новішою альтернативою для %оператора є використання str.format. Ось уривок із документації:

str.format(*args, **kwargs)

Виконайте операцію форматування рядків. Рядок, на який називається цей метод, може містити буквальний текст або поля заміни, обмежені дужками {}. Кожне поле заміни містить або числовий індекс позиційного аргументу, або ім'я аргументу ключового слова. Повертає копію рядка, де кожне поле заміни замінюється на значення рядка відповідного аргументу.

Цей метод є новим стандартом в Python 3.0, і його слід віддати перевагу %форматуванню .

Список літератури


Приклади

Ось кілька прикладів використання:

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

Дивитися також


У мене немає можливості перевірити це (я не знаю Python так багато), але приклади, здається, підказують, що щось на кшталт '{self.author} in {self.publication}'.format(self=self)повинно "працювати". Я просто не впевнений у всьому unicode.
полігенмастильні матеріали

1
Так, ви дійсно можете отримати доступ до атрибутів (а також індексів). Дивіться docs.python.org/library/string.html#formatstrings Отже, у своєму прикладі ви могли використати {first[0]}для отримання початкового J.
Дункан

10

Потрібно просто ввести значення в дужки:

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

Тут, за перший буде розміщений. А для другого , то буде використовуватися.%sunicode(self.author)%sunicode(self.publication)

Примітка: Ви повинні сприяти string formattingнад %нотації. Більше інформації тут


Я не можу повірити, що люди все ще пропонують, %sа тодіformat
користувач1767754

8

Існує значна проблема в деяких відповідях, розміщених до цих пір: unicode()декодує з кодування за замовчуванням, яке часто ASCII; насправді unicode()намагається зробити "сенс" байтів, які йому задані, перетворивши їх в символи. Таким чином, на моїй машині не вдається наступний код, який по суті є тим, що рекомендується попередніми відповідями:

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

дає:

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)

Відмова виникає з того, що authorне містить лише байтів ASCII (тобто зі значеннями в [0; 127]), а unicode()декодується від ASCII за замовчуванням (на багатьох машинах).

Надійне рішення - явно дати кодування, яке використовується у ваших полях; взявши UTF-8 як приклад:

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

(або без початкового u, залежно від того, чи потрібно результат Unicode або рядок байтів).

На даний момент, можна було б розглянути питання, що має authorі publicationполя є рядками Unicode, замість того, щоб декодувати їх під час форматування.


5

Для python2 ви також можете це зробити

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

що зручно, якщо у вас є багато аргументів на заміну (особливо якщо ви робите інтернаціоналізацію)

Підтримка Python2.6 і далі .format()

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

4

Ви також можете використовувати його чисто і просто (але неправильно! Тому що ви повинні використовувати так, formatяк сказав Марк Байєрс), виконуючи:

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

3

Для повноти, в PEP-498 введено пітон 3.6 f-string . Ці рядки дозволяють зробити це

вставляти вирази всередині рядкових літералів, використовуючи мінімальний синтаксис.

Це означає, що для вашого прикладу ви також можете використовувати:

f'{self.author} in {self.publication}'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.