Использование нескольких аргументов для форматирования строк в Python (например, "% s...% s" )

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

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

Но это не работает, так как это выглядит в Python?

Ответ 1

Ответ Mark Cidade прав - вам нужно поставить кортеж.

Однако из Python 2.6 вы можете использовать format вместо %:

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

Использование % для форматирования строк больше не рекомендуется.

Этот метод форматирования строк является новым стандартом в Python 3.0 и должен быть предпочтительнее% форматирования, описанного в операциях форматирования строк в новом коде.

Ответ 2

Если вы используете несколько аргументов, это должно быть в кортеже (обратите внимание на дополнительные круглые скобки):

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

Ответ 3

В объекте tuple/mapping для множественного аргумента format

Ниже приведена отрывок из документации:

Учитывая format % values, % спецификации преобразования в format заменяются на ноль или более элементов values. Эффект аналогичен использованию sprintf() на языке C.

Если для параметра 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

См. также

Ответ 4

Вы должны просто поместить значения в скобки:

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

Здесь для первого %s будет размещен unicode(self.author). А для второго %s будет использоваться unicode(self.publication).

Примечание: вам следует отдать предпочтение string formatting перед нотацией %. Подробнее здесь

Ответ 5

Существует значительная проблема с некоторыми ответами, опубликованными до сих пор: 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, а не декодировать их во время форматирования.

Ответ 6

Для 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)

Ответ 7

Вы также можете использовать его чистым и простым (но не так, потому что вы должны использовать format, как сказал Марк Байерс):

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

Ответ 8

Для полноты, в Python 3.6 f-строка введена в PEP-498. Эти строки позволяют

вставлять выражения в строковые литералы, используя минимальный синтаксис.

Это будет означать, что для вашего примера вы также можете использовать:

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