Skip to content

Latest commit

 

History

History
100 lines (71 loc) · 4.48 KB

File metadata and controls

100 lines (71 loc) · 4.48 KB

str

← float · 🏠 Домой · bool →


Что такое str и чем он отличается от bytes?

Коротко. str — неизменяемая последовательность символов Unicode. bytes — неизменяемая последовательность байтов. Между ними переходят явно: encode() в байты, decode() обратно.

'abc'.encode()              # b'abc'          — по умолчанию UTF-8
b'abc'.decode()             # 'abc'
len('\N{SNOWMAN}')          # 1  — один символ
len('\N{SNOWMAN}'.encode()) # 3  — три байта в UTF-8

Правило, которое стоит держать в голове: внутри программы — str, на границах (файлы, сеть, БД) — bytes с явно указанной кодировкой.

Подвох. str неизменяем, поэтому сборка строки в цикле через s += x на каждом шаге создаёт новый объект. Для этого есть ''.join(parts) — линейная сложность вместо квадратичной.


Как строка хранится в памяти?

Коротко. Гибко: CPython выбирает ширину символа по самому «широкому» символу в строке — 1, 2 или 4 байта (PEP 393).

Если в строке только ASCII/Latin-1, на символ уходит один байт. Появился хотя бы один символ из более широкого диапазона — вся строка переходит на UCS-2 или UCS-4:

import sys
sys.getsizeof('a' * 10)          # 51  — один байт на символ
sys.getsizeof('\U0001F642' + 'a' * 9)   # 100 — четыре байта на символ

Подвох. Частое заблуждение — «строки внутри хранятся в UTF-8». Нет: UTF-8 используется при кодировании и декодировании, а также как кеш для C API (PyUnicode_AsUTF8), но не как единственное внутреннее представление. Именно благодаря фиксированной ширине индексация s[i] работает за константное время.


Что нового в f-строках?

Коротко. python 3.12+ (PEP 701) снял ограничения на кавычки и вложенность.

# python 3.12+
name = "world"
print(f"{"hello"} {name}")      # раньше было SyntaxError
print(f"{f"{name.upper()}"}")   # вложенные f-строки

Полезный отладочный синтаксис — = внутри подстановки, печатает и выражение, и значение:

a = 5
f"{a = }"      # 'a = 5'

Что такое t-строки?

Коротко. python 3.14+ (PEP 750) — литерал t"...", который возвращает не готовую строку, а объект string.templatelib.Template со структурой: отдельно статические куски, отдельно подставленные значения.

# python 3.14+
name = "world"
t = t"Hello, {name}!"
t.strings          # ('Hello, ', '!')
t.interpolations   # (Interpolation(value='world', expression='name', ...),)

Смысл в безопасности: значения не подставляются «вслепую», их можно сначала обработать — экранировать под SQL, HTML или shell — и только потом собрать строку. Это тот же подход, что у параметризованных запросов, но на уровне языка.

Подвох. t-строка — не строка: str(t) не даст ожидаемого результата, и передать её туда, где ждут str, нельзя. Её должен обработать код, знающий про Template.


Остальные методы — в документации.


← float · 🏠 Домой · bool →