19.1.8. email.header: Интернационализированные заголовки¶email.header: Internationalized headers
Исходный код: Lib/email/header.py
RFC 2822 – это базовый стандарт, описывающий формат email-сообщений. Он происходит от более старого стандарта RFC 822, который получил широкое распространение в то время, когда большинство писем состояло только из символов ASCII. RFC 2822 – это спецификация, написанная в предположении, что email содержит только 7-битные символы ASCII.
Конечно, с распространением email по всему миру он стал интернационализированным, так что теперь в email-сообщениях можно использовать наборы символов, специфичные для языка. Базовый стандарт по-прежнему требует, чтобы email-сообщения передавались только с использованием 7-битных символов ASCII, поэтому был написан ряд RFC, описывающих, как кодировать email, содержащий не-ASCII символы, в формат, совместимый с RFC 2822. Эти RFC включают RFC 2045, RFC 2046, RFC 2047 и RFC 2231. Пакет email поддерживает эти стандарты в своих модулях email.header и email.charset.
Если вы хотите включить не-ASCII символы в заголовки email, например, в поля Subject или To, следует использовать класс Header и присвоить поле в объекте Message экземпляру Header вместо использования строки для значения заголовка. Импортируйте класс Header из модуля email.header. Например:
>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'
Обратите внимание, как мы хотели, чтобы поле Subject содержало не-ASCII символ? Мы сделали это, создав экземпляр Header и передав набор символов, в котором была закодирована байтовая строка. Когда последующий экземпляр Message был преобразован в плоскую строку, поле Subject было должным образом закодировано с помощью RFC 2047. Почтовые программы, поддерживающие MIME, покажут этот заголовок, используя встроенный символ ISO-8859-1.
Вот описание класса Header:
-
class
email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')¶ Создаёт заголовок, совместимый с MIME, который может содержать строки в разных наборах символов.
Необязательный параметр s – это начальное значение заголовка. Если
None(по умолчанию), начальное значение заголовка не установлено. Позже можно добавлять данные в заголовок с помощью вызовов методаappend(). s может быть экземпляромbytesилиstr, но смотрите документациюappend()о семантике.Необязательный параметр charset служит двум целям: он имеет то же значение, что и аргумент charset метода
append(). Он также устанавливает набор символов по умолчанию для всех последующих вызововappend(), в которых опущен аргумент charset. Если charset не указан в конструкторе (по умолчанию), набор символовus-asciiиспользуется как начальный набор символов для s, так и как набор по умолчанию для последующих вызововappend().Максимальную длину строки можно указать явно через maxlinelen. Чтобы первая строка разбивалась на более короткое значение (с учётом заголовка поля, который не входит в s, например Subject), передаётся имя поля в header_name. Значение по умолчанию maxlinelen – 76, а значение по умолчанию для header_name –
None, то есть он не учитывается для первой строки длинного разбитого заголовка.Необязательный параметр continuation_ws должен быть пробельным символом для переноса, совместимым с RFC 2822, и обычно это пробел или символ табуляции. Этот символ будет добавляться в начало строк продолжения. По умолчанию continuation_ws – это одиночный пробел.
Необязательный параметр errors передаётся напрямую методу
append().-
append(s, charset=None, errors='strict')¶ Добавляет строку s к MIME-заголовку.
Необязательный charset, если указан, должен быть экземпляром
Charset(см.email.charset) или именем набора символов, который будет преобразован в экземплярCharset. ЗначениеNone(по умолчанию) означает, что используется charset, указанный в конструкторе.s может быть экземпляром
bytesилиstr. Если это экземплярbytes, то charset – это кодировка этой байтовой строки, и будет возбуждено исключениеUnicodeError, если строка не может быть декодирована с этим набором символов.Если s является экземпляром
str, то charset – это подсказка, указывающая набор символов для символов в строке.В любом случае, при создании заголовка, совместимого с RFC 2822, с использованием правил RFC 2047, строка будет закодирована с помощью выходного кодека набора символов. Если строка не может быть закодирована с помощью выходного кодека, будет возбуждено исключение UnicodeError.
Необязательный errors передаётся как аргумент errors при вызове decode, если s является байтовой строкой.
-
encode(splitchars=';, \t', maxlinelen=None, linesep='\n')¶ Кодирует заголовок сообщения в формат, соответствующий RFC, возможно, перенося длинные строки и инкапсулируя не-ASCII части в кодировки base64 или quoted-printable.
Необязательный параметр splitchars – это строка, содержащая символы, которым алгоритм разбиения должен придавать дополнительный вес при обычном переносе заголовков. Это очень грубая поддержка «синтаксических разрывов более высокого уровня» из RFC 2822: точки разбиения, перед которыми стоит символ splitchar, предпочтительны при разбиении строки, причем символы предпочтительны в порядке их появления в строке. Пробел и табуляция могут быть включены в строку, чтобы указать, следует ли отдавать предпочтение одному перед другим в качестве точки разбиения, когда другие символы splitchar не встречаются в разбиваемой строке. Параметр splitchars не влияет на строки, закодированные по RFC 2047.
maxlinelen, если указан, переопределяет значение экземпляра для максимальной длины строки.
linesep задаёт символы, используемые для разделения строк свернутого заголовка. По умолчанию используется наиболее полезное значение для кода приложений Python (
\n), но можно указать\r\n, чтобы создавать заголовки с разделителями строк, соответствующими RFC.Изменено в версии 3.2: Добавлен аргумент linesep.
Класс
Headerтакже предоставляет ряд методов для поддержки стандартных операторов и встроенных функций.-
__str__()¶ Возвращает приближение объекта
Headerв виде строки с неограниченной длиной строки. Все фрагменты преобразуются в Unicode с использованием указанной кодировки и соответствующим образом объединяются. Любые фрагменты с charset'unknown-8bit'декодируются как ASCII с использованием обработчика ошибок'replace'.Изменено в версии 3.2: Добавлена обработка для charset
'unknown-8bit'.
-
Модуль email.header также предоставляет следующие удобные функции.
-
email.header.decode_header(header)¶ Декодирует значение заголовка сообщения без преобразования набора символов. Значение заголовка находится в header.
Эта функция возвращает список пар
(decoded_string, charset), содержащих каждую из декодированных частей заголовка. charset равноNoneдля незакодированных частей заголовка, в противном случае – это строка в нижнем регистре, содержащая имя кодировки, указанной в закодированной строке.Вот пример:
>>> from email.header import decode_header >>> decode_header('=?iso-8859-1?q?p=F6stal?=') [(b'p\xf6stal', 'iso-8859-1')]
-
email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')¶ Создаёт экземпляр
Headerиз последовательности пар, возвращаемой функциейdecode_header().Функция
decode_header()принимает строку значения заголовка и возвращает последовательность пар формата(decoded_string, charset), где charset – это имя набора символов.Эта функция принимает одну из таких последовательностей пар и возвращает экземпляр
Header. Необязательные параметры maxlinelen, header_name и continuation_ws такие же, как в конструктореHeader.