ChatGPT解决这个技术问题 Extra ChatGPT

使用 .format 时如何在字符串中打印大括号字符?

非工作示例:

print(" \{ Hello \} {0} ".format(42))

期望的输出:

 {Hello} 42 
对于那些想要避免双括号 ({{ }}) 的人,请使用 string.Template。在那里,您可以替换 $foo 形式的标识符(便于生成 LaTeX 代码)。
对于那些想要避免双括号,并且不反对在他们的 Python 项目中添加另一个依赖项的人,还有 Jinja2 通过允许用户定义的自定义占位符分隔符语法明确地解决了这个问题。

B
Boris Verkhovskiy

您需要将 {{}} 加倍:

>>> x = " {{ Hello }} {0} "
>>> print(x.format(42))
' { Hello } 42 '

以下是 Python documentation for format string syntax 的相关部分:

格式字符串包含用大括号 {} 包围的“替换字段”。大括号中未包含的任何内容都被视为文字文本,它会原封不动地复制到输出中。如果您需要在文字文本中包含大括号字符,可以通过加倍来转义:{{ 和 }}。


所以如果你想打印“{42}”,你会使用 "{{{0}}}".format(42)
如果你想要一个花括号怎么办? "{ something { } {value}".format(42) 不起作用。
"{{".format() 和 "}}".format() 打印单个花括号。在您的示例中: print "{{ something {{ }} {0}".format(42) 将打印 "{ something { } 42"。
{0} 是什么意思?
@Imray:{0} 指的是 .format() 的第一个参数。只要您为 .format() 提供相同数量的参数,您就可以打印多个值,例如 {0} docs.python.org/library/string.html#format-examples {0}。有关详细示例,请参阅 docs.python.org/library/string.html#format-examples
B
Bryan Bryce

Python 3.6+ (2017)

在最新版本的 Python 中,人们将使用 f-strings(另请参阅 PEP498)。

对于 f 字符串,应该使用双 {{}}

n = 42  
print(f" {{Hello}} {n} ")

产生所需的

 {Hello} 42

如果您需要解析括号中的表达式而不是使用文字文本,则需要三组括号:

hello = "HELLO"
print(f"{{{hello.lower()}}}")

生产

{hello}

my_greet = "HELLO" 可以得到 {hello} 作为输出,只使用 2 组括号和 print(f"{ {my_greet.lower()} }")。只需在括号之间留一个空格即可。
如果您在 rona 时代使用 Python3.6+,这现在应该是公认的答案。
@Gwi7d31 不,f 字符串不能替代 str.format()。例如,this answer I wrote 不可能用于 f 字符串,因为模板来自输入,而不是源代码。
@wjandrea 您的链接确实与 OPs 问题无关。当您通过 .format() 和字典解包方法在链接的答案中删除它们时,OP 希望保留花括号。如果您想在 Python 3.6+ 中保留 {},并且想在字符串中插入一个值,this is the way。这就是手头的问题。我也从未说过 f-strings 可以替代 .format()。你之前这么说。
@Gwi 我的意思是,这个问题是关于 str.format(),而不是 f 字符串,它们不相互兼容。
B
Boris Verkhovskiy

你通过加倍大括号来逃避它。

例如:

x = "{{ Hello }} {0}"
print(x.format(42))

N
Nick T

OP 写了这条评论:

我试图出于某些目的格式化一个小的 JSON,例如:'{"all": false, "selected":"{}"}'.format(data) 以获得类似 {"all": false, "选择”:“1,2”}

在处理 JSON 时出现“转义大括号”问题是很常见的。

我建议这样做:

import json
data = "1,2"
mydict = {"all": "false", "selected": data}
json.dumps(mydict)

它比替代方案更清洁,即:

'{{"all": false, "selected": "{}"}}'.format(data)

当 JSON 字符串比示例更复杂时,使用 json 库绝对是首选。


阿门!这似乎需要更多的工作,但使用库来做图书馆应该做的事情,而不是偷工减料……可以做更好的事情。
但是不能保证 Python 对象中键的顺序......不过,可以保证 JSON 库以 JSON 方式序列化。
wizzwizz4:好点。从 Python 3.6 开始,字典是按插入顺序排列的,所以这不是问题。 2.7 和 3.5 之间的 Python 版本可以使用集合库中的 OrderedDict。
如果,例如 data = 'foo"',另一种选择也是非常错误的,因为 data 的值中的 " 不会被正确转义。
如果您正在处理 JSON,那么此答案适合您。它在可读性和可维护性方面获胜——想象一下处理复杂的 JSON 结构和其中的大量双括号
m
mccc

您想用字符 {} 格式化字符串

你只需要把它们加倍。

f'{{'}f'}}' 格式化 {

所以 :

name = "bob"
print(f'Hello {name} ! I want to print }} and {{')

输出 :

你好鲍勃!我想打印 } 和 {


p
pajton

尝试这个:

x = "{{ Hello }} {0}"


D
DNR

尝试这样做:

x = " {{ Hello }} {0} "
print x.format(42)

G
George Aprilis

虽然不是更好,但仅供参考,您也可以这样做:

>>> x = '{}Hello{} {}'
>>> print x.format('{','}',42)
{Hello} 42

例如,当有人想要打印 {argument} 时,它可能很有用。它可能比 '{{{}}}'.format('argument') 更具可读性

请注意,您在 Python 2.7 之后省略了参数位置(例如 {} 而不是 {0}


R
Richard

如果需要在字符串中保留两个花括号,则需要在变量的每一侧使用 5 个花括号。

>>> myvar = 'test'
>>> "{{{{{0}}}}}".format(myvar)
'{{test}}'

对于那些使用 f 字符串的人,在两边使用 4 个花括号而不是 5 个
@TerryA .format 和 f 字符串之间的大括号行为没有区别。代码 a = 1; print('{{{{{a}}}}}'.format(a=a)) 产生与 a = 1; print(f'{{{{{a}}}}}') 相同的结果。
c
ccpizza

f 字符串(python 3)

您可以避免通过使用 f-strings ONLY 来处理您希望应用 f-magic 的字符串部分,并使用常规 (dumb ) 所有文字的字符串,可能包含“不安全”的特殊字符。 Let python do the string joining 只需将多个字符串堆叠在一起即可。

number = 42
print(" { Hello }"  
f" {number} " 
"{ thanks for all the fish }")

### OUTPUT:
{ Hello } 42 { thanks for all the fish }

注意:字符串之间的换行不是必需的。我添加它们只是为了便于阅读。您也可以编写上面的代码,如下所示: ⚠️ 警告:这可能会伤害您的眼睛或让您头晕目眩! print("{Hello}"f"{number}""{感谢所有的鱼}")


d
defiant
key = "FOOBAR"
print(f"hello {{{key}}}")

输出

hello {FOOBAR}

如果有人想使用 fstrings 在大括号内打印一些东西。


t
tvt173

如果您要经常这样做,那么定义一个实用函数可能会很好,它可以让您使用任意大括号替换,例如

def custom_format(string, brackets, *args, **kwargs):
    if len(brackets) != 2:
        raise ValueError('Expected two brackets. Got {}.'.format(len(brackets)))
    padded = string.replace('{', '{{').replace('}', '}}')
    substituted = padded.replace(brackets[0], '{').replace(brackets[1], '}')
    formatted = substituted.format(*args, **kwargs)
    return formatted

>>> custom_format('{{[cmd]} process 1}', brackets='[]', cmd='firefox.exe')
'{{firefox.exe} process 1}'

请注意,这将适用于作为长度为 2 的字符串的括号或两个字符串的可迭代(对于多字符分隔符)。


也想过这个。当然,这也可以,而且算法更简单。但是,假设你有很多这样的文本,你只想在这里和那里参数化它。每次创建输入字符串时,您都不想手动替换所有这些大括号。您只想在这里和那里“插入”您的参数化。在这种情况下,我认为从用户的角度来看,这种方法更容易思考和完成。我受到 linux 的“sed”命令的启发,该命令具有类似的功能,可以根据方便随意选择分隔符。
简而言之,我宁愿让效用函数稍微复杂一点,也不愿让@$$ 每次都使用起来很痛苦。如果我误解了你的提议,请告诉我。
我已经在我的 public.lab 空间中添加了一个简短的演示github.com/dreftymac/public.lab/blob/master/topic/python/…
K
Kristján Valur

我最近遇到了这个问题,因为我想将字符串注入到预先格式化的 JSON 中。我的解决方案是创建一个辅助方法,如下所示:

def preformat(msg):
    """ allow {{key}} to be used for formatting in text
    that already uses curly braces.  First switch this into
    something else, replace curlies with double curlies, and then
    switch back to regular braces
    """
    msg = msg.replace('{{', '<<<').replace('}}', '>>>')
    msg = msg.replace('{', '{{').replace('}', '}}')
    msg = msg.replace('<<<', '{').replace('>>>', '}')
    return msg

然后,您可以执行以下操作:

formatted = preformat("""
    {
        "foo": "{{bar}}"
    }""").format(bar="gas")

如果性能不是问题,则可以完成工作。


简单而优雅地集成到现有代码中,几乎不需要修改。谢谢!
当然,假设您的文本从不包含任何 <<<>>>,否则它们将被覆盖。最好使用逃生策略来提高可靠性!
你建议什么逃生策略?无论如何,您知道您的模板文本并且可以修改魔术字符串以防您担心冲突。
P
Puddles

我参加这个聚会迟到可笑。我成功地将括号放在替换元素中,如下所示:

print('{0} {1}'.format('{hello}', '{world}'))

哪个打印

{hello} {world}

严格来说,这不是 OP 所要求的,因为他/她想要格式字符串中的大括号,但这可能会对某人有所帮助。


M
Mohideen bin Mohammed

原因是,{}.format() 的语法,因此在您的情况下,.format() 无法识别 {Hello},因此它引发了错误。

您可以使用双花括号 {{}} 覆盖它,

x = " {{ Hello }} {0} "

或者

尝试 %s 的文本格式,

x = " { Hello } %s"
print x%(42)  

A
Ann Zen

您可以使用“引用墙”将格式化字符串部分与常规字符串部分分开。

从:

print(f"{Hello} {42}")

print("{Hello}"f" {42}")

一个更清楚的例子是

string = 10
print(f"{string} {word}")

输出:

NameError: name 'word' is not defined

现在,像这样添加报价墙:

string = 10
print(f"{string}"" {word}")

输出:

10 {word}

这看起来更像是串联,但很好的想法
我建议不要这样做——它使用的语言特性本身就存在争议,Guido 将其描述为错误(隐式字符串连接),并以一种本身不寻常且因此令人困惑的方式使用它。许多遇到此问题的人将很难弄清楚发生了什么。它本质上只是 f"{string}" + " {word}" 简单明了,但这样做更令人困惑。它让我想起了在 elem ,= {'single_element'} 中使用的虚假的“获取集合运算符的单个元素” ,= ,它有效但只会引起混乱!
D
DalyaG

如果您只想打印花括号的一侧:

a=3
print(f'{"{"}{a}')
>>> {3

不必要,将 { 加倍如最佳答案中所述仍然足够。所以f'{{{a}'
v
v.tralala

我在尝试打印文本时偶然发现了这个问题,我可以将其复制粘贴到 Latex 文档中。我在 this answer 上进行扩展并使用命名替换字段:

https://i.stack.imgur.com/YQt0F.gif

idx_mapping = {'i1':42, 'i2':3141, 'i3':2178 }
print('$A_{{ {i1:04d} }} * A_{{ {i2:04d} }} * A_{{ {i3:04d} }} * A_{{ {i1:04d} }}$'.format(**idx_mapping))

p
perfecto25

我使用双 {{ }} 来防止 fstring 值注入,

例如,继承我的 Postgres UPDATE 语句来更新一个整数数组列,该列采用 {} 的表达式来捕获数组,即:

端口 = '{100,200,300}'

用 fstrings 它,

ports = [1,2,3]

query = f"""
   UPDATE table SET ports = '{{{ports}}}' WHERE id = 1
"""

实际的查询语句将是,

UPDATE table SET ports = '{1,2,3}'

这是一个有效的 postgres 语句


L
Luis Cabrera Benito

如果您想打印一个花括号(例如 {),您可以使用 {{,如果需要,您可以稍后在字符串中添加更多花括号。例如:

>>> f'{{ there is a curly brace on the left. Oh, and 1 + 1 is {1 + 1}'
'{ there is a curly brace on the left. Oh, and 1 + 1 is 2'

C
Chetan Goyal

您可以通过使用原始字符串方法来做到这一点,只需在字符串前添加不带引号的字符 'r'。

# to print '{I am inside braces}'
print(r'{I am inside braces}')

你好!您可能需要重新检查; Python 3.7 打印 \{I am inside braces\}
@Teodor 对此感到抱歉。现在我通过打印为原始字符串来解决这个问题。
B
BPL

当您只是尝试插入代码字符串时,我建议使用 jinja2,它是 Python 的全功能模板引擎,即:

from jinja2 import Template

foo = Template('''
#include <stdio.h>

void main() {
    printf("hello universe number {{number}}");
}
''')

for i in range(2):
    print(foo.render(number=i))

因此,您不会被强制复制花括号,因为所有其他答案都暗示了这一点


我同意避免重复花括号是一件好事——但与其使用 jinja2,我只需要使用 python 自己的 string.Template 类,它对于这种事情来说已经足够强大了。
R
RunOrVeith

如果您需要可以格式化的 f 字符串模板中的花括号,您需要在 f 字符串的一组花括号中输出一个包含两个花括号的字符串:

css_template = f"{{tag}} {'{{'} margin: 0; padding: 0;{'}}'}"
for_p = css_template.format(tag="p")
# 'p { margin: 0; padding: 0;}'

这个问题与 f-strings 无关,而 IMO 以这种方式将 f-strings 和格式结合起来会产生非常不可读的代码
这是当你用谷歌搜索如何在 python f-strings 中放置花括号时出现的第一个结果,是的,我同意它并不漂亮,但有时你只需要它。
M
Mortz

或者只是参数化支架本身?可能非常冗长。

x = '{open_bracket}42{close_bracket}'.format(open_bracket='{', close_bracket='}') 
print(x)
# {42}

A
Abhishek

使用转义序列来转义 f 字符串中的花括号。例如:打印(f'{a={1}}')


OP 确实使用了转义序列并报告它们不起作用。此处的示例无法编译。此答案不会为之前发布的十五个答案增加任何价值。