Вопрос-Ответ

String formatting: % vs. .format vs. f-string literal

Форматирование строк: % vs .format vs . f-строковый литерал

Существуют различные методы форматирования строк:


  • Python <2.6: "Hello %s" % name

  • Python 2.6+: "Hello {}".format(name) (использует str.format)

  • Python 3.6+: f"{name}" (использует f-строки)

Что лучше и для каких ситуаций?



  1. Следующие методы дают одинаковый результат, так в чем же разница?


    name = "Alice"

    "Hello %s" % name
    "Hello {0}".format(name)
    f"Hello {name}"

    # Using named arguments:
    "Hello %(kwarg)s" % {'kwarg': name}
    "Hello {kwarg}".format(kwarg=name)
    f"Hello {name}"


  2. Когда выполняется форматирование строк и как мне избежать снижения производительности во время выполнения?




Если вы пытаетесь закрыть повторяющийся вопрос, который просто ищет способ форматирования строки, пожалуйста, используйте Как мне поместить значение переменной внутрь строки?.

Переведено автоматически
Ответ 1

Отвечаю на ваш первый вопрос... .format Просто кажется более сложным во многих отношениях. Раздражает то, что % также заключается в том, что он может принимать либо переменную, либо кортеж. Можно подумать, что всегда будет работать следующее:

"Hello %s" % name

тем не менее, если name произойдет (1, 2, 3), он выдаст TypeError . Чтобы гарантировать, что он всегда печатается, вам нужно будет сделать

"Hello %s" % (name,)   # supply the single argument as a single-item tuple

это просто уродливо. у.format нет этих проблем. Также во втором примере, который вы привели, .format пример выглядит намного чище.

Используйте его только для обратной совместимости с Python 2.5.


Чтобы ответить на ваш второй вопрос, форматирование строки происходит одновременно с любой другой операцией - при вычислении выражения форматирования строки. И Python, не будучи ленивым языком, вычисляет выражения перед вызовом функций, поэтому выражение log.debug("some debug info: %s" % some_info) сначала вычислит строку до, например, "some debug info: roflcopters are active", затем эта строка будет передана log.debug().

Ответ 2

Что-то, чего не может сделать оператор modulo ( % ), afaik:

tu = (12,45,22222,103,6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)

Результат

12 22222 45 22222 103 22222 6 22222

Очень полезно.

Еще один момент: format(), будучи функцией, может использоваться в качестве аргумента в других функциях:

li = [12,45,78,784,2,69,1254,4785,984]
print map('the number is {}'.format,li)

print

from datetime import datetime,timedelta

once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0)
delta = timedelta(days=13, hours=8, minutes=20)

gen =(once_upon_a_time +x*delta for x in xrange(20))

print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))

Приводит к:

['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984']

2010-07-01 12:00:00
2010-07-14 20:20:00
2010-07-28 04:40:00
2010-08-10 13:00:00
2010-08-23 21:20:00
2010-09-06 05:40:00
2010-09-19 14:00:00
2010-10-02 22:20:00
2010-10-16 06:40:00
2010-10-29 15:00:00
2010-11-11 23:20:00
2010-11-25 07:40:00
2010-12-08 16:00:00
2010-12-22 00:20:00
2011-01-04 08:40:00
2011-01-17 17:00:00
2011-01-31 01:20:00
2011-02-13 09:40:00
2011-02-26 18:00:00
2011-03-12 02:20:00
Ответ 3

Предполагая, что вы используете logging модуль Python, вы можете передать аргументы форматирования строк в качестве аргументов .debug() методу, а не выполнять форматирование самостоятельно:

log.debug("some debug info: %s", some_info)

который позволяет избежать форматирования, если регистратор действительно что-то не регистрирует.

Ответ 4

Начиная с версии Python 3.6 (2016), вы можете использовать f-strings для замены переменных:

>>> origin = "London"
>>> destination = "Paris"
>>> f"from {origin} to {destination}"
'from London to Paris'

Обратите внимание на f" префикс. Если вы попробуете это в Python 3.5 или более ранней версии, вы получите SyntaxError.

См . https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings

python performance