【发布时间】:2019-01-06 05:16:56
【问题描述】:
我正在尝试漂亮地打印一个 HTTP 请求(我在这里模拟过)。
from typing import NamedTuple
class RequestMock(NamedTuple):
method = 'POST'
url = 'https://bob.com'
body = 'body1\nbody2'
headers = {'a': '1', 'b': '2'}
我有一个功能可以做到这一点:
req = RequestMock()
def print1(req):
headers = '\n'.join(f'{k}: {v}' for k, v in req.headers.items())
s = '\n'.join([
f'{req.method} {req.url}',
headers,
req.body
])
print(s)
print1(req)
# POST https://bob.com
# a: 1
# b: 2
# body1
# body2
但是当我为了清晰和易于修改而尝试用f-strings 重写它时,我得到了一些不好的缩进:
# what I want the code to look like
def print2(req):
headers = '\n'.join(f'{k}: {v}' for k, v in req.headers.items())
s = f"""
{req.method} {req.url}
{headers}
{req.body}
"""
print(s)
print2(req)
# POST https://bob.com
# a: 1
# b: 2
# body1
# body2
我知道这是因为我使用换行符定义字符串并将它们放在三引号字符串中。有没有一种简单的方法可以使用在函数中定义的三引号 f-string 来获取我正在查看的输出,而不必知道其定义的缩进级别?我玩过textwrap.indent、textwrap.dedent、str.lstrip、re 等,但代码不再简单和 Pythonic 快。我想出的最接近的是以下内容,但长度很尴尬,我觉得我在重复自己。
def print3(req):
headers = '\n'.join(f'{k}: {v}' for k, v in req.headers.items())
s = textwrap.dedent("""
{method} {url}
{headers}
{body}
""").strip()
s = s.format(
method=req.method,
url=req.url,
headers=headers,
body=req.body,
)
print(s)
print3(req)
# POST https://bob.com
# a: 1
# b: 2
# body1
# body2
【问题讨论】:
-
注意:我试图让this 更具可读性
-
您可以在
print()的括号内将普通的python 字符串链接在一起。这样,您只需按 Enter 即可添加更多内容。 -
@GeeTransit 我真正感兴趣的是 formatting 字符串的更一般的概念。然后我可以随意通过他们。
-
'\n'.join(line.lstrip() for line in f'''insert \n multiline \n string \n here \n {variable}'''.split('\n')) -
在评论中看起来很奇怪...它使用三重引号
f-strings,因此您只需在前面添加部分,离开中间,然后添加结尾.split('\n')。
标签: python formatting f-string