Ben*_*Ben 10 python formatting f-string
我正在尝试漂亮地打印一个 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等,但是代码不再简单,也不再像 Python 那样快速。我想出的最接近的内容如下,但长度很尴尬,我觉得我在重复自己。
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
我认为您可以尝试利用隐式字符串连接来获得半美观的解决方案:
def print4(req):
    headers = '\n'.join(f'{k}: {v}' for k, v in req.headers.items())
    s = (f'{req.method} {req.url}\n'
         f'{headers}\n'
         f'{req.body}')
    print(s)
print4(req)
输出:
POST https://bob.com
a: 1
b: 2
body1
body2
请注意,如果需要,您可以去掉括号并使用反斜杠:
s = f'{req.method} {req.url}\n' \
    f'{headers}\n'              \
    f'{req.body}'
但是,样式指南更喜欢括号而不是反斜杠。
另外一个选择:
def print5(req):
    headers = '\n'.join(f'{k}: {v}' for k, v in req.headers.items())
    s = f"""
    {req.method} {req.url}
    {headers}
    {req.body}
    """
    s = '\n'.join(l.lstrip() for l in s.splitlines())
    print(s)
| 归档时间: | 
 | 
| 查看次数: | 24320 次 | 
| 最近记录: |