Использование нескольких аргументов для форматирования строки в 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, и его следует предпочитать форматированию%, описанному в Операциях форматирования строк в новом коде.

Марк Байерс
источник
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

Смотрите также

polygenelubricants
источник
У меня нет возможности проверить это (я не очень хорошо знаю 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
user1767754
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)
Lordn__n
источник
3

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

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

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

f'{self.author} in {self.publication}'
westr
источник