Python для пацанов.
134 subscribers
2 photos
9 links
"Серьезный" разбор языка программирования Пайтон для серьезных пацанов.
Download Telegram
PEP 750: t-строки в 3.14

В питон добавили еще один способ форматировать строки. Теперь – со специальным АПИ для внешних интеграций.

- PEP: https://peps.python.org/pep-0750
- Реализация: https://github.com/python/cpython/pull/132662

Основная причина: использовать f строки удобно, но нет никакого АПИ для перехвата момента "вставки" или интерполяции значений. Например, при форматировании html или sql – требуется специальным образом делать escape для значений. И раньше код вида f"<div>{template}</div>" представлял собой дыру в безопасности и потенциальное место для XSS.

string.templatelib.Template

Новый префикс t не будет создавать объект str, он будет создавать объект класса string.templatelib.Template:


>>> user = 'sobolevn'
>>> template = t"Hi, {user}"
>>> template
Template(strings=('Hi, ', ''), interpolations=(Interpolation('sobolevn', 'user', None, ''),))

>>> from string.templatelib import Template
>>> isinstance(template, Template)
True


Обратите внимание, что при создании template – у нас не произошло форматирование сразу. Мы создали объект, у которого есть свойства strings и interpolations, из которых можно собрать финальную отформатированную строку.

Давайте посмотрим на примере. Допустим, мы хотим формировать URL из наших данных:


>>> domain = 'example.com'
>>> query = 'python string formatting is too complex'
>>> template = t'https://{domain}?q={query}'


И сам код логики форматирования, где мы будем вставлять значения разным способом. Если у нас шаблон query, то мы будем использовать quote_plus для его форматирования. Остальные значения – будем вставлять как есть:


>>> from string.templatelib import Template, Interpolation
>>> from urllib.parse import quote_plus

>>> def format_url(template: Template) -> str:
... parts = []
... for part in template:
... match part:
... case str() as s: # regular string
... parts.append(s)
... case Interpolation(value, expression='query'):
... parts.append(quote_plus(value))
... case Interpolation(value):
... parts.append(value)
... return ''.join(parts)


И вот результат:


>>> format_url(template)
'https://example.com?q=python+string+formatting+is+too+complex'


Только теперь наш Template был отформатирован. Нами. Ручками.
У нас есть полный контроль за процессом форматирования. Вот в чем суть данного ПЕПа.

Фичи одной строкой

- Работает = как обычно в f строках: t'{user=}'
- Есть привычные определители формата: !r, !s, .2f, тд
- t строки можно конкатенировать: t'Hello' + t' , world!' и t'Hello, ' + 'world'
- Поддерживается режим raw строк: rt"Hi \n!"

Как устроено внутри?

Интересные места имплементации:
- Изменения лексера
- Изменения грамматики языка
- Новое CAPI _PyTemplate
- Новые классы Template и Interpolation написанные на C
- Новый байткод BUILD_INTERPOLATION и BUILD_TEMPLATE


>>> import dis
>>> user = 'sobolevn'
>>> dis.dis('t"Hi, {user}"')
0 RESUME 0

1 LOAD_CONST 2 (('Hi, ', ''))
LOAD_NAME 0 (user)
LOAD_CONST 1 ('user')
BUILD_INTERPOLATION 2
BUILD_TUPLE 1
BUILD_TEMPLATE
RETURN_VALUE


Обсуждение: как вам еще один способ форматирования строк?

| Поддержать | YouTube | GitHub | Чат |
👍71