【问题标题】:Why is a list not allowed with format strings?为什么列表不允许使用格式字符串?
【发布时间】:2015-08-15 07:54:29
【问题描述】:

为什么元组(或字典)必须与格式字符串一起使用:

"%s %d" % ("text", 42)

以下会有什么缺点?

"%s %d" % ["text", 42]

【问题讨论】:

  • 因为语法是defined to use a tuple or mapping object。与您不会使用双引号来定义整数文字的原因相同。他们很可能让它使用列表,但为什么要这样做呢?
  • 好问题。我不知道,但我怀疑这与列表的可变性有关
  • the source 中没有给出解释。我猜原因是“因为它需要大量的工作来实现,而且没有足够的人想要它”
  • 有点奇怪,规则是如果它是一个元组,则解包,否则调用__str__。如果规则是在只有一种格式规范的情况下调用__str__,并在有多个格式规范时尝试解包,那么它自然会适用于任何合理的事情。
  • 我的猜测是让 *args 更容易传递给 C printf()-like 内部函数。

标签: python string format-specifiers


【解决方案1】:

我在猜测,但我希望这是因为 GvR 想要最大限度地减少 T 导致 'my object is: %s' % T(...) 失败的不同类型的数量。 namedtuples 失败已经够糟糕了 ;-)

也就是说,允许'%s %s' % [1,2] 会为粗心的人创建一个额外的陷阱,因为它会阻止您将[1,2] 本身格式化为%s 格式。

【讨论】:

    【解决方案2】:

    最有可能在格式化字符串时使用元组来解决歧义。也就是说,假设您有一个不可变的对象,例如列表或字典,这些对象将来可能会更改,因此格式化可能会失败,或者它的格式可能与您预期的不一样!实际上,元组的使用比使用列表要清晰得多,这是因为元组不能像列表一样在宫内更改。

    例如,考虑以下代码:

    T = ("spam", "ham")
    
    s = "%s and %s" % T
    

    因为左边的对象是一个元组,你可以确保在程序运行时它永远不会被一个操作就地改变,这样你就可以放心了。但是,并不是说使用元组是完全安全的,因为您可以执行 T += ("holy cow",) 之类的操作,因此您将在元组中添加第三项,这会使表达式错误。元组虽然比列表更不可能改变,因为它们是不可变的对象。一个列表可能会在任何地方更改,谁知道该列表可能在百万行程序中何时何地更改?

    注意当我们在这里使用列表时会发生什么:

    L = ["spam", "ham"]
    L.append("Ice-cream")        #line 103984.. above "%s and %s" % L 
    
    s = "%s and %s" % L              #Error, three values in L  
    

    您可能认为L 仅包含"spam""ham",但实际上L 包含另一个在程序运行时从操作中添加的对象。您可能会在较小的系统中自己检测到此错误,但想一想如果列表 L 用于在巨大系统中的函数之间进行状态保留,您将如何知道它的价值或可能发生的变化?更糟糕的是,您可能希望将s 传递给函数以某种方式处理格式化的字符串,如果它依赖于某种字符串格式,您的函数将立即失败。如果没有特定的字符串格式,它可能会处理您想要颠倒的操作。

    这可能不明确,因为您需要跟踪所有代码;当然,这在大型系统中是一项乏味的任务。列表不受更改的保护,反之亦然,您应该按照自己的意愿更改和操作列表。因为列表可以不时更改,Python 仅在格式化表达式中使用元组来避免这种混淆。通常,元组是列表的一种类型,但它们是常量,您不能就地更改它们。这从字面上简化了调试程序的操作。

    【讨论】:

    • 我认为您在初始化和使用之间更改列表的观点是有效的。不幸的是,还有很多其他方面与问题无关或令人困惑......
    【解决方案3】:

    元组比列表访问更快,这使其成为默认值

    【讨论】:

    • 这真的重要吗?毕竟我们正在格式化字符串,这永远不会很快,即永远不应该在时间关键的代码中完成。此外,通常在元组中使用 1 到 10 个元素。
    猜你喜欢
    • 2010-11-10
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多