Я пытаюсь красиво распечатать 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
и т. Д., Но код перестает быть простым и быстрым. Самое близкое, что я придумал, это следующее, но длина неловкая, и я чувствую, что повторяюсь.
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