译(三十八)-Python三种字符串格式化对比:% .format f‘string’

stackoverflow热门问题目录

如有翻译问题欢迎评论指出,谢谢。

自我感觉今天的翻译更人话了点。

三种字符串格式化对比:% .format f‘string’

  • NorthIsUp asked:

    • Python 2.6 有一个 str.format() 方法,和现有的 % 操作符有点不同。它们各自更适合哪些情况?
    • Python 3.6 则提出了另一种字符串格式化语法 f"my string" ,它和其它方法又有什么优势?
    1. 下面代码使用了三种不同的方法,但输出相同,到底有啥区别?

      #!/usr/bin/python
      sub1 = "python string!"
      sub2 = "an arg"
      #
      sub_a = "i am a %s" % sub1
      sub_b = "i am a {0}".format(sub1)
      sub_c = f"i am a {sub1}"
      #
      arg_a = "with %(kwarg)s!" % {'kwarg':sub2}
      arg_b = "with {kwarg}!".format(kwarg=sub2)
      arg_c = f"with {sub2}!"
      #
      print(sub_a)    # "i am a python string!"
      print(sub_b)    # "i am a python string!"
      print(sub_c)    # "i am a python string!"
      #
      print(arg_a)    # "with an arg!"
      print(arg_b)    # "with an arg!"
      print(arg_c)    # "with an arg!"
    2. 此外,对于 Python 而言,应该在什么时候使用字符串格式化?比如日志级别设置为 HIGH 时使用 % 会不会有影响?如果有的话,怎么避免?

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

    • Claudiu – vote: 976

    • 对于第一个问题而言,.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 还更美观点。

    • 哪些情况下不会用到这个方法?

      1. 不清楚这个方式(没读到这之前我就是这样的)
      2. 为了和 Python 2.5 兼容

    • 对于第二个问题而言,字符串格式化常常会与其它操作同时出现——字符串格式化会先于这些操作。Python 会在调用函数前先计算表达式结果,所以对于 log.debug 这个例子来说,表达式 "some debug info: %s"%some_info 将首先得到 "some debug info: roflcopters are active",然后再将字符串传给 log.debug()

    • eyquem – vote: 314

    • 有些是模运算符 % 做不到的,据我所知下面的就不行:

    • 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
    • Wooble – vote: 154

    • 对于 Python 的 logging 模块而言,可以将字符串格式化的参数作为 .debug() 方法的参数,这样就不用先自己格式化它了:

    • log.debug("some debug info: %s", some_info)
    • 这可以在没有东西需要格式化时,避免格式化操作。


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

  • NorthIsUp asked:

    • Python 2.6 introduced the str.format() method with a slightly different syntax from the existing % operator. Which is better and for what situations?
      Python 2.6 有一个 str.format() 方法,和现有的 % 操作符有点不同。它们各自更适合哪些情况?
    • Python 3.6 has now introduced another string formatting format of string literals (aka f strings) via the syntax f"my string". Is this formatting option better than the others?
      Python 3.6 则提出了另一种字符串格式化语法 f"my string" ,它和其它方法又有什么优势?
    1. The following uses each method and has the same outcome, so what is the difference?
      下面代码使用了三种不同的方法,但输出相同,到底有啥区别?

      #!/usr/bin/python
      sub1 = "python string!"
      sub2 = "an arg"
      #
      sub_a = "i am a %s" % sub1
      sub_b = "i am a {0}".format(sub1)
      sub_c = f"i am a {sub1}"
      #
      arg_a = "with %(kwarg)s!" % {'kwarg':sub2}
      arg_b = "with {kwarg}!".format(kwarg=sub2)
      arg_c = f"with {sub2}!"
      #
      print(sub_a)    # "i am a python string!"
      print(sub_b)    # "i am a python string!"
      print(sub_c)    # "i am a python string!"
      #
      print(arg_a)    # "with an arg!"
      print(arg_b)    # "with an arg!"
      print(arg_c)    # "with an arg!"
    2. Furthermore when does string formatting occur in Python? For example, if my logging level is set to HIGH will I still take a hit for performing the following % operation? And if so, is there a way to avoid this?
      此外,对于 Python 而言,应该在什么时候使用字符串格式化?比如日志级别设置为 HIGH 时使用 % 会不会有影响?如果有的话,怎么避免?

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

    • Claudiu – vote: 976

    • To answer your first question… .format just seems more sophisticated in many ways. An annoying thing about % is also how it can either take a variable or a tuple. You\’d think the following would always work:
      对于第一个问题而言,.format 更适合于大多数情况。% 有一点很讨厌,它能传入变量或元组,所以你可能觉得下面这样是正确的:

    • "hi there %s" % name
    • yet, if name happens to be (1, 2, 3), it will throw a TypeError. To guarantee that it always prints, you\’d need to do
      但当 name 恰好是 (1, 2, 3) 时,就会抛出 TypeError。而为了保证它始终有输出,就得这样:

    • "hi there %s" % (name,)   # supply the single argument as a single-item tuple
    • which is just ugly. .format doesn\’t have those issues. Also in the second example you gave, the .format example is much cleaner looking.
      很丑对吧。.format 就不会有这些毛病。而且对于你给出的第二个例子而言,.format 还更美观点。

    • Why would you not use it?
      哪些情况下不会用到这个方法?

      1. not knowing about it (me before reading this)
        不清楚这个方式(没读到这之前我就是这样的)
      2. having to be compatible with Python 2.5
        为了和 Python 2.5 兼容

    • To answer your second question, string formatting happens at the same time as any other operation – when the string formatting expression is evaluated. And Python, not being a lazy language, evaluates expressions before calling functions, so in your log.debug example, the expression some debug info: %s"%some_info will first evaluate to, e.g. "some debug info: roflcopters are active", then that string will be passed to log.debug().
      对于第二个问题而言,字符串格式化常常会与其它操作同时出现——字符串格式化会先于这些操作。Python 会在调用函数前先计算表达式结果,所以对于 log.debug 这个例子来说,表达式 "some debug info: %s"%some_info 将首先得到 "some debug info: roflcopters are active",然后再将字符串传给 log.debug()

    • eyquem – vote: 314

    • Something that the modulo operator ( % ) can\’t do, afaik:
      有些是模运算符 % 做不到的,据我所知下面的就不行:

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

    • 12 22222 45 22222 103 22222 6 22222
    • Very useful.
      这玩意非常好使。

    • Another point: format(), being a function, can be used as an argument in other functions:
      还有一点: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))
    • Results in:
      输出:

    • ['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
    • Wooble – vote: 154

    • Assuming you\’re using Python\’s logging module, you can pass the string formatting arguments as arguments to the .debug() method rather than doing the formatting yourself:
      对于 Python 的 logging 模块而言,可以将字符串格式化的参数作为 .debug() 方法的参数,这样就不用先自己格式化它了:

    • log.debug("some debug info: %s", some_info)
    • which avoids doing the formatting unless the logger actually logs something.
      这可以在没有东西需要格式化时,避免格式化操作。

You may also like...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注