【问题标题】:python's ".format" functionpython的“.format”函数
【发布时间】:2012-04-26 23:19:57
【问题描述】:

最近,我发现''.format 函数非常有用,因为与% 格式相比,它可以大大提高可读性。 尝试实现简单的字符串格式化:

data = {'year':2012, 'month':'april', 'location': 'q2dm1'}

year = 2012
month = 'april'
location = 'q2dm1'
a = "year: {year}, month: {month}, location: {location}"
print a.format(data)
print a.format(year=year, month=month, location=location)
print a.format(year, month, location)

虽然前两个打印的格式符合我的预期(是的,something=something 看起来很丑,但这只是一个示例),最后一个会引发KeyError: 'year'。 python中是否有任何技巧来创建字典,以便它会自动填充键和值,例如somefunc(year, month, location)将输出{'year':year, 'month': month, 'location': location}

我对 python 很陌生,找不到关于这个主题的任何信息,但是这样的技巧会大大改善和缩小我当前的代码。

先谢谢了,请原谅我的英语。

【问题讨论】:

    标签: python string dictionary formatting


    【解决方案1】:

    Python 3.6 开始,您还可以使用新的Formatted string literals (f-strings),您可以将其与变量一起使用:

    year = 2012
    month = 'april'
    location = 'q2dm1'
    a = f"year: {year}, month: {month}, location: {location}"
    print(a)
    

    字典

    data = {'year': 2012, 'month': 'april', 'location': 'q2dm1'}
    a = f"year: {data['year']}, month: {data['month']}, location: {data['location']}"
    print(a)
    

    注意字符串文字前的 f 前缀。

    PEP 498: Formatted string literals:

    格式化的字符串字面量以 'f' 为前缀,类似于 str.format() 接受的格式字符串。它们包含替换 花括号包围的字段。替换字段是 表达式,在运行时计算,然后使用 format() 协议:

    >>>
    >>> name = "Fred"
    >>> f"He said his name is {name}."
    'He said his name is Fred.'
    >>> width = 10
    >>> precision = 4
    >>> value = decimal.Decimal("12.34567")
    >>> f"result: {value:{width}.{precision}}"  # nested fields
    'result:      12.35'
    

    ...

    【讨论】:

      【解决方案2】:
      data = {'year':2012, 'month':'april', 'location': 'q2dm1'}
      a = "year: {year}, month: {month}, location: {location}"
      
      print a.format(**data)
      

      ..是你要找的。它在功能上与 .format(year=data['year'], ...) 或您提供的其他示例相同。

      双星号的东西很难搜索,所以它通常被称为“kwargs”。这是good SO question on this syntax

      【讨论】:

        【解决方案3】:

        你可以通过locals():

        a.format(**locals())
        

        当然,这有问题:您必须在本地传递所有内容,并且很难理解重命名或删除变量的效果。

        更好的方法是:

        a.format(**{k:v for k,v in locals() if k in ('year', 'month')})
        # or; note that if you move the lambda expression elsewhere, you will get a different result
        a.format(**(lambda ld = locals(): {k:ld[k] for k in ('year', 'month')})())
        

        但这不再简洁了,除非你用一个函数把它包装起来(当然它必须带一个 dict 参数)。

        【讨论】:

          【解决方案4】:

          您可以使用dict() 可调用:

          dict(year=yeah, month=month, location=location)
          

          当传递关键字参数时,它会创建一个包含您指定为 kwargs 的元素的字典。

          如果不想指定参数名称,请使用.format()的位置样式:

          >>> a = 'year {0} month {1} location {2}'
          >>> print a.format(2012, 'april', 'abcd')
          year 2012 month april location abcd
          

          但是,如果您尝试做类似于compact() in PHP 所做的事情(创建一个将变量名称映射到其值的字典,而不单独指定名称和变量),请不要这样做。它只会导致难以阅读的丑陋代码,并且无论如何都需要令人讨厌的黑客攻击。

          【讨论】:

          • 是的,我知道 dict() 但我试图避免不必要的代码并将其缩小一点。 .format 可以接受您的选择,而无需 dict() 顺便说一句。谢谢。
          • 谢谢,它已经接近我需要的了,但是使用 10-12 个参数,在索引中导航变得非常困难。
          • 那么在这种情况下,您应该使用 dict 语法。但是,根据您想要做什么,可以考虑使用真正的模板引擎,例如jinja2
          • 感谢模板指导。
          • 另外,只是添加,dict 不是函数。 dict 是一种类型。
          【解决方案5】:

          第一个print应该是

          print a.format(**data)
          

          另外,如果你正在寻找一些捷径,你可以写一个类似的,没有太大区别。

          def trans(year, month, location):
              return dict(year=year, month=month, location=location)
          

          【讨论】:

          • 似乎没有办法缩小这个重复代码:) 功能很好,实际上我就是这样做的,但后来我发现它很难维持,因为有很多参数我需要更改代码几个地方,结果证明比手动创建字典还要糟糕。
          • @duke_nukem 是的,这取决于您的实际使用情况。代码很好,格式api也够清晰。如果你想达到format(*args, **kwargs) 之类的目标,也可以这样做,但我认为这不会让事情变得更容易。
          猜你喜欢
          • 2011-06-25
          • 1970-01-01
          • 1970-01-01
          • 2022-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-18
          相关资源
          最近更新 更多