Форматирование строки:% против .format - PullRequest
1292 голосов
/ 22 февраля 2011

В Python 2.6 введен метод str.format() с немного отличающимся синтаксисом от существующего оператора %.Что лучше и для каких ситуаций?

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

    #!/usr/bin/python
    sub1 = "python string!"
    sub2 = "an arg"
    
    a = "i am a %s" % sub1
    b = "i am a {0}".format(sub1)
    
    c = "with %(kwarg)s!" % {'kwarg':sub2}
    d = "with {kwarg}!".format(kwarg=sub2)
    
    print a    # "i am a python string!"
    print b    # "i am a python string!"
    print c    # "with an arg!"
    print d    # "with an arg!"
    
  2. Кроме того, когда происходит форматирование строки в Python?Например, если мой уровень ведения журнала установлен на ВЫСОКИЙ, я все равно получу удар для выполнения следующей операции %?И если да, есть ли способ избежать этого?

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

Ответы [ 16 ]

13 голосов
/ 04 июля 2018

Если ваш питон> = 3.6, литерал в формате F - ваш новый друг.

Это более просто, чисто и лучше.

In [1]: params=['Hello', 'adam', 42]

In [2]: %timeit "%s %s, the answer to everything is %d."%(params[0],params[1],params[2])
448 ns ± 1.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: %timeit "{} {}, the answer to everything is {}.".format(*params)
449 ns ± 1.42 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit f"{params[0]} {params[1]}, the answer to everything is {params[2]}."
12.7 ns ± 0.0129 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
9 голосов
/ 09 апреля 2015

Может помочь %, когда вы форматируете выражения регулярных выражений. Например,

'{type_names} [a-z]{2}'.format(type_names='triangle|square')

повышает IndexError. В этой ситуации вы можете использовать:

'%(type_names)s [a-z]{2}' % {'type_names': 'triangle|square'}

Это позволяет избежать записи регулярного выражения как '{type_names} [a-z]{{2}}'. Это может быть полезно, когда у вас есть два регулярных выражения, где один используется один без формата, но объединение обоих форматируется.

5 голосов
/ 16 апреля 2018

Я бы добавил, что начиная с версии 3.6 мы можем использовать fstrings, как показано ниже

foo = "john"
bar = "smith"
print(f"My name is {foo} {bar}")

которые дают

Меня зовут Джон Смит

Все преобразуется в строки

mylist = ["foo", "bar"]
print(f"mylist = {mylist}")

Результат:

mylist = ['foo', 'bar']

Вы можете передать функцию, как в методе других форматов

print(f'Hello, here is the date : {time.strftime("%d/%m/%Y")}')

Давать например

Здравствуйте, вот дата: 16/04/2018

2 голосов
/ 15 февраля 2018

Для версии Python> = 3,6 (см. PEP 498 )

s1='albha'
s2='beta'

f'{s1}{s2:>10}'

#output
'albha      beta'
1 голос
/ 05 февраля 2019

Python 3.6.7 сравнительный:

#!/usr/bin/env python
import timeit

def time_it(fn):
    """
    Measure time of execution of a function
    """
    def wrapper(*args, **kwargs):
        t0 = timeit.default_timer()
        fn(*args, **kwargs)
        t1 = timeit.default_timer()
        print("{0:.10f} seconds".format(t1 - t0))
    return wrapper


@time_it
def new_new_format(s):
    print("new_new_format:", f"{s[0]} {s[1]} {s[2]} {s[3]} {s[4]}")


@time_it
def new_format(s):
    print("new_format:", "{0} {1} {2} {3} {4}".format(*s))


@time_it
def old_format(s):
    print("old_format:", "%s %s %s %s %s" % s)


def main():
    samples = (("uno", "dos", "tres", "cuatro", "cinco"), (1,2,3,4,5), (1.1, 2.1, 3.1, 4.1, 5.1), ("uno", 2, 3.14, "cuatro", 5.5),) 
    for s in samples:
        new_new_format(s)
        new_format(s)
        old_format(s)
        print("-----")


if __name__ == '__main__':
    main()

Выход:

new_new_format: uno dos tres cuatro cinco
0.0000170280 seconds
new_format: uno dos tres cuatro cinco
0.0000046750 seconds
old_format: uno dos tres cuatro cinco
0.0000034820 seconds
-----
new_new_format: 1 2 3 4 5
0.0000043980 seconds
new_format: 1 2 3 4 5
0.0000062590 seconds
old_format: 1 2 3 4 5
0.0000041730 seconds
-----
new_new_format: 1.1 2.1 3.1 4.1 5.1
0.0000092650 seconds
new_format: 1.1 2.1 3.1 4.1 5.1
0.0000055340 seconds
old_format: 1.1 2.1 3.1 4.1 5.1
0.0000052130 seconds
-----
new_new_format: uno 2 3.14 cuatro 5.5
0.0000053380 seconds
new_format: uno 2 3.14 cuatro 5.5
0.0000047570 seconds
old_format: uno 2 3.14 cuatro 5.5
0.0000045320 seconds
-----
1 голос
/ 25 августа 2018

Но одна вещь состоит в том, что также, если у вас есть вложенные фигурные скобки, не будет работать для формата, но % будет работать.

Пример:

>>> '{{0}, {1}}'.format(1,2)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    '{{0}, {1}}'.format(1,2)
ValueError: Single '}' encountered in format string
>>> '{%s, %s}'%(1,2)
'{1, 2}'
>>> 
...