Unicode
Werkzeug использует строки внутри повсюду, где предполагаются текстовые данные, даже если стандарт HTTP не поддерживает Unicode. В основном все входные данные декодируются из кодировки символов (по умолчанию UTF-8), чтобы вы не работали напрямую с байтами. Исходящие данные кодируются в целевую кодировку символов.
Unicode в Python
Представьте, что у вас есть немецкая умлаут ö. В ASCII вы не можете представить этот символ, но в latin-1 и utf-8 наборах символов вы можете его представить, но они выглядят по-разному при кодировании:
>>> "ö".encode("latin1")
b'\xf6'
>>> "ö".encode("utf-8")
b'\xc3\xb6'
Один ö выглядит по-разному в зависимости от кодировки, что затрудняет работу с ним в виде байтов. Вместо этого Python рассматривает строки как текст Unicode и хранит информацию LATIN SMALL LETTER O WITH DIAERESIS вместо байтов для ö в определенной кодировке. Длина строки с 1 символом будет 1, тогда как длина байтов может быть другим значением.
Unicode в HTTP
Однако спецификация HTTP была написана в то время, когда байты ASCII были распространённым способом представления данных. Чтобы обойти это для современного веб-приложения, Werkzeug автоматически декодирует и кодирует входные и выходные данные. Данные, отправляемые из браузера веб-приложению, декодируются из байтов UTF-8 в строку. Данные, отправляемые от приложения обратно в браузер, кодируются обратно в UTF-8.
Обработка ошибок
Функции, выполняющие внутреннее кодирование или декодирование, принимают ключевое слово errors , которое передаётся в str.decode() и str.encode(). Значение по умолчанию — 'replace' , чтобы ошибки легко обнаруживались. Может быть полезно установить его на 'strict' , чтобы поймать ошибку и сообщить о некорректных данных клиенту.
Объекты запроса и ответа
В большинстве случаев следует использовать по умолчанию кодировку UTF-8 Werkzeug. Если у вас есть особая причина, вы можете создать подкласс wrappers.Request и wrappers.Response, чтобы изменить кодировку и обработку ошибок.
from werkzeug.wrappers.request import Request
from werkzeug.wrappers.response import Response
class Latin1Request(Request):
charset = "latin1"
encoding_errors = "strict"
class Latin1Response(Response):
charset = "latin1"
Обработка ошибок может быть изменена только для запроса. Werkzeug всегда будет генерировать ошибки при кодировании в байты в ответе. Вы несете ответственность за то, чтобы не создавать данные, которые отсутствуют в целевой кодировке символов. Это не проблема для UTF-8.
© 2007–2021 Pallets
Licensed under the BSD 3-clause License.
https://werkzeug.palletsprojects.com/en/2.0.x/unicode/