协慌网

登录 贡献 社区

Python 字符串格式:%vs. .format

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 中发生字符串格式化?例如,如果我的日志记录级别设置为 HIGH,我仍然会执行以下%操作吗?如果是这样,有没有办法避免这种情况?

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

答案

回答你的第一个问题...... .format在很多方面看起来都比较复杂。关于%一个烦人的事情也是它如何采用变量或元组。您认为以下内容始终有效:

"hi there %s" % name

但是,如果name恰好是(1, 2, 3) ,它将抛出TypeError 。为了保证它始终打印,您需要这样做

"hi there %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()

模数运算符(%)不能做的事情,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

假设您正在使用 Python 的logging模块,您可以将字符串格式化参数作为参数传递给.debug()方法,而不是自己进行格式化:

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

这避免了格式化,除非记录器实际记录的东西。