是否有与 Ruby 的字符串插值等效的 Python?

Posted

技术标签:

【中文标题】是否有与 Ruby 的字符串插值等效的 Python?【英文标题】:Is there a Python equivalent to Ruby's string interpolation? 【发布时间】:2011-05-25 22:27:07 【问题描述】:

Ruby 示例:

name = "Spongebob Squarepants"
puts "Who lives in a Pineapple under the sea? \n#name."

成功的 Python 字符串连接对我来说似乎很冗长。

【问题讨论】:

这里的问题是 name 是一个位于字符串中的局部变量,在 Python 中,如果您希望它使用它们,则必须将局部变量的字典显式传递给字符串格式化程序。 这不是最初的问题,但谢谢。您的评论让我对变量范围有了更好的理解(我仍在了解这一点)。 :) 那你觉得这个怎么样? ***.com/questions/16504732/… PEP 215 -- String Interpolation - 被python.org/dev/peps/pep-0292取代 请参阅***.com/a/33264516/55721 了解 3.6 中的确切功能 【参考方案1】:

Python 3.6 将添加literal string interpolation,类似于 Ruby 的字符串插值。从该版本的 Python(计划于 2016 年底发布)开始,您将能够在“f-strings”中包含表达式,例如

name = "Spongebob Squarepants"
print(f"Who lives in a Pineapple under the sea? name.")

在 3.6 之前,最接近这个的是

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? %(name)s." % locals())

% 运算符可用于 Python 中的 string interpolation。第一个操作数是要插值的字符串,第二个操作数可以有不同的类型,包括“映射”,将字段名称映射到要插值的值。这里我使用了局部变量字典locals()将字段名称name映射到它的值作为一个局部变量。

使用最新 Python 版本的.format() 方法的相同代码如下所示:

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? name!s.".format(**locals()))

还有string.Template类:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.")
print(tmpl.substitute(name="Spongebob Squarepants"))

【讨论】:

@Caste 看这里:docs.python.org/library/stdtypes.html#string-formatting 如果您需要更多详细信息,请发表后续评论 我了解它的基本要点,但是我并不完全了解文档示例中的所有附加符号和文本。为什么在这里使用转换为字符串:%(language)s '03d' 中的 3 表示什么?为什么字符串后面有%\? print 表达式之后的变量分配(如果它们实际上是变量)也让我感到困惑。对不起,如果这很痛苦! 示例中使用的两种基本格式是 %s 用于字符串,%03d 用于填充到前导零的 3 位数字。它可以写成print "%s has %03d" % ("Python", 2)。然后,该示例使用将映射键放在 % 之后的括号中,这是一种为占位符提供有意义的名称而不是依赖于它们在字符串中的顺序的方法。然后,您传递一个将键名映射到它们的值的字典。这就是 Sven 使用 locals() 函数的原因,该函数返回一个包含所有局部变量的字典,因此它将 name 映射到 name 的值 转换类型的必要用法首先让我感到困惑。因此,使用文档术语。 % 开始说明符。 (语言)没有转换标志,只有转换类型(尾随's'); (number) 但是有一个(或两个)转换标志,分别为“0”(和“3”)。 'd' 是转换类型,表示它是一个整数。我理解正确吗? @Caste:是的,这基本上是对的。请注意,您始终可以使用s 作为转换类型——Python 几乎可以将任何内容转换为字符串。但是,您当然会失去其他转换类型的特殊格式化功能。【参考方案2】:

从 Python 2.6.X 开始,您可能想要使用:

"my 0 string: 1".format("cool", "Hello there!")

【讨论】:

请注意,用于字符串插值的 % 运算符在 Python 3.x 中被弃用。 docs.python.org/dev/py3k/whatsnew/… 宣布计划从 3.1 开始弃用 %,但这从未发生过。 %-syntax 仍然存在于 Python 3 中(自 Python 3.2 起未弃用) 请注意: 中的数字我可以去掉。【参考方案3】:

我开发了interpy 包,它在 Python 中启用字符串插值

只需通过pip install interpy 安装即可。 然后,在文件开头添加# coding: interpy 行!

例子:

#!/usr/bin/env python
# coding: interpy

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n#name."

【讨论】:

这看起来真的很不安全。 @d33tah:不,只要在编译时字符串是已知的。【参考方案4】:

Python 的字符串插值类似于 C 的 printf()

如果你尝试:

name = "SpongeBob Squarepants"
print "Who lives in a Pineapple under the sea? %s" % name

标签%s 将替换为name 变量。你应该看看打印功能标签:http://docs.python.org/library/functions.html

【讨论】:

我如何用 2 个变量做到这一点? @JulioMarins 使用元组:print "First is %s, second is %s" % (var1, var2)【参考方案5】:

字符串插值将是included with Python 3.6 as specified in PEP 498。您将能够做到这一点:

name = 'Spongebob Squarepants'
print(f'Who lives in a Pineapple under the sea? \nname')

请注意,我讨厌海绵宝宝,所以写这篇文章有点痛苦。 :)

【讨论】:

感谢海绵宝宝的引用 (/distaste):现在要投票赞成。【参考方案6】:

这个也可以

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \nname.".format(name=name)

http://docs.python.org/2/library/string.html#formatstrings

【讨论】:

我不相信 OP 打算打印 #。他们只是使用 Ruby 语法。 你是对的。我编辑了答案。我对Ruby不熟悉,所以我认为#字符会被打印出来。【参考方案7】:
import inspect
def s(template, **kwargs):
    "Usage: s(string, **locals())"
    if not kwargs:
        frame = inspect.currentframe()
        try:
            kwargs = frame.f_back.f_locals
        finally:
            del frame
        if not kwargs:
            kwargs = globals()
    return template.format(**kwargs)

用法:

a = 123
s('a', locals()) # print '123'
s('a') # it is equal to the above statement: print '123'
s('b') # raise an KeyError: b variable not found

PS:性能可能有问题。这对本地脚本很有用,而不是生产日志。

重复:

Python string formatting: % vs. .format

What is the Python equivalent of embedding an expression in a string? (ie. "#expr" in Ruby)

What is Ruby equivalent of Python's `s= "hello, %s. Where is %s?" % ("John","Mary")`

Is there a Python equivalent to Ruby's string interpolation?

【讨论】:

【参考方案8】:

对于旧 Python(在 2.4 上测试),最佳解决方案指明了方向。你可以这样做:

import string

def try_interp():
    d = 1
    f = 1.1
    s = "s"
    print string.Template("d: $d f: $f s: $s").substitute(**locals())

try_interp()

然后你得到

d: 1 f: 1.1 s: s

【讨论】:

【参考方案9】:

Python 3.6 和更新版本有 literal string interpolation 使用 f-strings:

name='world'
print(f"Hello name!")

【讨论】:

以上是关于是否有与 Ruby 的字符串插值等效的 Python?的主要内容,如果未能解决你的问题,请参考以下文章

是否有与 Ruby 符号等效的 Python?

是否有与 PHP 的 preg_replace 等效的 MySQL?

是否有与 Haskell 'let' 等效的 Python

Blazor 中是不是有与 Html.Raw 等效的内容?

是否有与 FontUtilities.getCompositeFontUIResource(Font) 等效的非专有等效项?

是否有与 RecyclerView 等效的 addHeaderView?