email.message.Message
: Представляет сообщение электронной почты с использованием compat32
API¶
Класс Message
очень похож на класс EmailMessage
, но в нем отсутствуют методы, добавленные этим классом, а поведение некоторых других методов по умолчанию немного отличается. Здесь также описаны некоторые методы, которые, хотя и поддерживаются классом EmailMessage
, не рекомендуются, если вы не имеете дело с устаревшим кодом.
В остальном философия и структура этих двух классов одинаковы.
В этом документе описывается поведение в соответствии с политикой по умолчанию (для Message
) Compat32
. Если вы собираетесь использовать другую политику, вам следует использовать класс EmailMessage
.
Сообщение электронной почты состоит из заголовков и полезной нагрузки. Заголовки должны содержать имена и значения в стиле RFC 5322, где имя поля и значение разделены двоеточием. Двоеточие не является частью ни имени поля, ни значения поля. Полезной нагрузкой может быть простое текстовое сообщение, или двоичный объект, или структурированная последовательность вложенных сообщений, каждое из которых имеет свой собственный набор заголовков и свою собственную полезную нагрузку. Последний тип полезной нагрузки обозначается сообщением, имеющим MIME-тип, такой как multipart/* или message/rfc822.
Концептуальная модель, предоставляемая объектом Message
, представляет собой упорядоченный словарь заголовков с дополнительными методами для доступа как к специализированной информации из заголовков, так и к полезной нагрузке, для генерации сериализованной версии сообщения и для рекурсивного обхода дерева объектов. Обратите внимание, что дублирующиеся заголовки поддерживаются, но для доступа к ним необходимо использовать специальные методы.
Псевдослов Message
индексируется по именам заголовков, которые должны быть значениями ASCII. Значения словаря представляют собой строки, которые, как предполагается, должны содержать только символы ASCII; существует некоторая специальная обработка для ввода данных, отличных от ASCII, но она не всегда приводит к правильным результатам. Заголовки сохраняются и возвращаются в форме с сохранением регистра, но имена полей сопоставляются без учета регистра. Также может быть один заголовок конверта, также известный как заголовок Unix-From или заголовок From_
. Полезная нагрузка * представляет собой строку или байты, в случае простых объектов сообщений, или список объектов Message
для документов-контейнеров MIME (например, multipart/* и message/rfc822).
Вот методы класса Message
:
- class email.message.Message(policy=compat32)¶
Если указана политика (это должен быть экземпляр класса
policy
), используйте указанные в ней правила для обновления и сериализации представления сообщения. Если параметр policy не задан, используйте политикуcompat32
, которая поддерживает обратную совместимость с версией почтового пакета Python 3.2. Для получения дополнительной информации обратитесь к документацииpolicy
.Изменено в версии 3.3: Был добавлен аргумент ключевого слова policy.
- as_string(unixfrom=False, maxheaderlen=0, policy=None)¶
Возвращает все сообщение в сжатом виде в виде строки. Если параметр unixfrom имеет значение true, заголовок конверта включается в возвращаемую строку. unixfrom по умолчанию имеет значение
False
. По соображениям обратной совместимости значение maxheaderlen по умолчанию равно0
, поэтому, если вам нужно другое значение, вы должны явно переопределить его (значение, указанное для max_line_length в политике, будет проигнорировано этим методом). Аргумент policy может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может быть использовано для управления некоторым форматированием, создаваемым методом, поскольку указанная политика будет передана вGenerator
.Сглаживание сообщения может вызвать изменения в
Message
, если для завершения преобразования в строку необходимо ввести значения по умолчанию (например, могут быть сгенерированы или изменены границы MIME).Обратите внимание, что этот метод предоставляется для удобства и не всегда может форматировать сообщение так, как вы хотите. Например, по умолчанию он не изменяет строки, начинающиеся с
From
, что требуется в формате mbox Unix. Для большей гибкости создайте экземплярGenerator
и используйте его методflatten()
напрямую. Например:from io import StringIO from email.generator import Generator fp = StringIO() g = Generator(fp, mangle_from_=True, maxheaderlen=60) g.flatten(msg) text = fp.getvalue()
Если объект сообщения содержит двоичные данные, которые не закодированы в соответствии со стандартами RFC, несоответствующие данные будут заменены кодовыми точками unicode «неизвестный символ». (Смотрите также
as_bytes()
иBytesGenerator
.)Изменено в версии 3.4: был добавлен аргумент ключевого слова policy.
- __str__()¶
Эквивалентно
as_string()
. Позволяетstr(msg)
создать строку, содержащую отформатированное сообщение.
- as_bytes(unixfrom=False, policy=None)¶
Возвращает все сообщение в сжатом виде в виде объекта bytes. Если параметр unixfrom имеет значение true, заголовок конверта включается в возвращаемую строку. unixfrom по умолчанию имеет значение
False
. Аргумент policy может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может использоваться для управления некоторым форматированием, создаваемым методом, поскольку указанная политика будет передана вBytesGenerator
.Сглаживание сообщения может вызвать изменения в
Message
, если для завершения преобразования в строку необходимо ввести значения по умолчанию (например, могут быть сгенерированы или изменены границы MIME).Обратите внимание, что этот метод предоставляется для удобства и не всегда может форматировать сообщение так, как вы хотите. Например, по умолчанию он не изменяет строки, начинающиеся с
From
, что требуется в формате mbox Unix. Для большей гибкости создайте экземплярBytesGenerator
и используйте его методflatten()
напрямую. Например:from io import BytesIO from email.generator import BytesGenerator fp = BytesIO() g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60) g.flatten(msg) text = fp.getvalue()
Добавлено в версии 3.4.
- __bytes__()¶
Эквивалентно
as_bytes()
. Позволяетbytes(msg)
создать объект bytes, содержащий отформатированное сообщение.Добавлено в версии 3.4.
- is_multipart()¶
Возвращает
True
, если полезной нагрузкой сообщения является список вложенных объектовMessage
, в противном случае возвращаетFalse
. Когдаis_multipart()
возвращаетFalse
, полезной нагрузкой должен быть строковый объект (который может быть двоичной полезной нагрузкой в кодировке CTE). ((Обратите внимание, чтоis_multipart()
, возвращающийTrue
, не обязательно означает, что «msg.get_content_maintype() == „multipart“» вернетTrue
. Например,is_multipart
вернетTrue
, еслиMessage
имеет типmessage/rfc822
.)
- set_unixfrom(unixfrom)¶
Установите в заголовке конверта сообщения значение unixfrom, которое должно быть строкой.
- get_unixfrom()¶
Возвращает заголовок конверта сообщения. По умолчанию используется значение
None
, если заголовок конверта никогда не задавался.
- attach(payload)¶
Добавьте заданную полезную нагрузку к текущей полезной нагрузке, которая должна быть
None
или списком объектовMessage
перед вызовом. После вызова полезной нагрузкой всегда будет список объектовMessage
. Если вы хотите задать полезную нагрузку в виде скалярного объекта (например, строки), используйте вместо этогоset_payload()
.Это устаревший метод. В классе
EmailMessage
его функциональность заменена наset_content()
и связанные с ним методыmake
иadd
.
- get_payload(i=None, decode=False)¶
Возвращает текущую полезную нагрузку, которая будет представлять собой список объектов
Message
, когдаis_multipart()
равноTrue
, или строку, когдаis_multipart()
равноFalse
. Если полезной нагрузкой является список, и вы изменяете объект списка, вы изменяете полезную нагрузку сообщения на месте.С необязательным аргументом i,
get_payload()
возвращает i-й элемент полезной нагрузки, считая от нуля, еслиis_multipart()
равноTrue
. ЗначениеIndexError
будет выдано, если значение i меньше 0 или больше или равно количеству элементов в полезной нагрузке. Если полезная нагрузка представляет собой строку (т.е.is_multipart()
равноFalse
) и задано значение i, генерируется значениеTypeError
.Необязательный decode - это флаг, указывающий, следует ли декодировать полезную нагрузку или нет, в соответствии с заголовком Content-Transfer-Encoding. Когда
True
и сообщение не состоит из нескольких частей, полезная нагрузка будет декодирована, если значение этого заголовка равноquoted-printable
илиbase64
. Если используется какая-либо другая кодировка или заголовок Content-Transfer-Encoding отсутствует, полезная нагрузка возвращается как есть (без декодирования). Во всех случаях возвращаемое значение является двоичными данными. Если сообщение состоит из нескольких частей и флаг decode равенTrue
, то возвращаетсяNone
. Если полезной нагрузкой является base64 и она была сформирована неидеально (отсутствуют отступы, символы не соответствуют алфавиту base64), то в свойство defect сообщения будет добавлен соответствующий дефект (InvalidBase64PaddingDefect
илиInvalidBase64CharactersDefect
соответственно).Когда значение decode равно
False
(по умолчанию), тело возвращается в виде строки без декодирования Content-Transfer-Encoding. Однако для 8-битного Content-Transfer-Encoding выполняется попытка декодирования исходных байтов с использованиемcharset
, указанного в заголовке Content-Type, с использованием обработчика ошибокreplace
. Если не указаноcharset
или если указанныйcharset
не распознается почтовым пакетом, текст сообщения декодируется с использованием кодировки ASCII по умолчанию.Это устаревший метод. В классе
EmailMessage
его функциональность заменена наget_content()
иiter_parts()
.
- set_payload(payload, charset=None)¶
Установите для полезной нагрузки всего объекта сообщения значение полезная нагрузка. Клиент несет ответственность за обеспечение инвариантности полезной нагрузки. Необязательный charset устанавливает набор символов сообщения по умолчанию; подробности см. в
set_charset()
.Это устаревший метод. В классе
EmailMessage
его функциональность заменена наset_content()
.
- set_charset(charset)¶
Задайте для набора символов полезной нагрузки значение charset, которое может быть либо экземпляром
Charset
(см.email.charset
), строкой с именем набора символов, либоNone
. Если это строка, то она будет преобразована в экземплярCharset
. Если кодировка равнаNone
, параметрcharset
будет удален из заголовка Content-Type (сообщение не будет изменено иным образом). Все остальное приведет к появлениюTypeError
.Если нет существующего заголовка MIME-Version, то будет добавлен один. Если нет существующего заголовка Content-Type, то будет добавлен заголовок со значением text/plain. Независимо от того, существует заголовок Content-Type или нет, его параметру
charset
будет присвоено значение charset.output_charset. Если charset.input_charset и charset.output_charset отличаются, полезная нагрузка будет перекодирована в output_charset. Если заголовок Content-Transfer-Encoding не существует, то полезная нагрузка будет закодирована для передачи, при необходимости, с использованием указанногоCharset
, и будет добавлен заголовок с соответствующим значением. Если заголовок Content-Transfer-Encoding уже существует, предполагается, что полезная нагрузка уже правильно закодирована с использованием этого Content-Transfer-Encoding и не изменяется.Это устаревший метод. В классе
EmailMessage
его функциональность заменена параметром charset методаemail.emailmessage.EmailMessage.set_content()
.
- get_charset()¶
Возвращает экземпляр
Charset
, связанный с полезной нагрузкой сообщения.Это устаревший метод. В классе
EmailMessage
он всегда возвращаетNone
.
Следующие методы реализуют интерфейс, подобный отображению, для доступа к заголовкам сообщения RFC 2822. Обратите внимание, что между этими методами и обычным интерфейсом отображения (т.е. словарем) существуют некоторые семантические различия. Например, в словаре нет повторяющихся ключей, но здесь могут быть повторяющиеся заголовки сообщений. Кроме того, в словарях нет гарантированного порядка для ключей, возвращаемых
keys()
, но в объектеMessage
заголовки всегда возвращаются в том порядке, в котором они появились в исходном сообщении или были добавлены в сообщение позже. Любой удаленный, а затем повторно добавленный заголовок всегда добавляется в конец списка заголовков.Эти семантические различия являются намеренными и направлены на максимальное удобство.
Обратите внимание, что во всех случаях любой заголовок конверта, присутствующий в сообщении, не включается в интерфейс сопоставления.
В модели, сгенерированной из байтов, любые значения заголовка, которые (в нарушение RFC) содержат байты, отличные от ASCII, при извлечении через этот интерфейс будут представлены как объекты
Header
с кодировкойunknown-8bit
.- __len__()¶
Возвращает общее количество заголовков, включая дубликаты.
- __contains__(name)¶
Возвращает
True
, если в объекте сообщения есть поле с именем name. Сопоставление выполняется без учета регистра, и name не должно содержать двоеточие в конце. Используется для оператораin
, например:if 'message-id' in myMessage: print('Message-ID:', myMessage['message-id'])
- __getitem__(name)¶
Возвращает значение именованного поля заголовка. имя не должно содержать двоеточие, разделяющее поля. Если заголовок отсутствует, возвращается
None
; значениеKeyError
никогда не задается.Обратите внимание, что если именованное поле появляется в заголовках сообщения более одного раза, то не определено, какое именно из значений этого поля будет возвращено. Используйте метод
get_all()
, чтобы получить значения всех существующих именованных заголовков.
- __setitem__(name, val)¶
Добавьте заголовок к сообщению с именем поля name и значением val. Поле добавляется в конец существующих полей сообщения.
Обратите внимание, что это не приводит к замене или удалению любого существующего заголовка с таким же именем. Если вы хотите убедиться, что новый заголовок является единственным, который присутствует в сообщении с именем поля, сначала удалите это поле, например:
del msg['subject'] msg['subject'] = 'Python roolz!'
- __delitem__(name)¶
Удалите все упоминания поля с именем name из заголовков сообщения. Исключение не возникает, если именованное поле отсутствует в заголовках.
- keys()¶
Возвращает список всех имен полей заголовка сообщения.
- values()¶
Возвращает список всех значений полей сообщения.
- items()¶
Возвращает список из 2 кортежей, содержащий все заголовки и значения полей сообщения.
- get(name, failobj=None)¶
Возвращает значение поля именованного заголовка. Это значение идентично
__getitem__()
, за исключением того, что необязательный failobj возвращается, если именованный заголовок отсутствует (по умолчанию используетсяNone
).
Вот несколько дополнительных полезных методов:
- get_all(name, failobj=None)¶
Возвращает список всех значений для поля с именем name. Если в сообщении нет таких именованных заголовков, возвращается failobj (по умолчанию
None
).
- add_header(_name, _value, **_params)¶
Расширенная настройка заголовка. Этот метод аналогичен
__setitem__()
, за исключением того, что в качестве аргументов ключевого слова могут быть предоставлены дополнительные параметры заголовка. _name - это поле заголовка для добавления, а _value - это основное значение для заголовка.Для каждого элемента в словаре аргументов ключевого слова _params в качестве имени параметра берется ключ, а символы подчеркивания преобразуются в тире (поскольку тире недопустимы в идентификаторах Python). Обычно параметр добавляется как
key="value"
, если только его значение не равноNone
, и в этом случае будет добавлен только ключ. Если значение содержит символы, отличные от ASCII, оно может быть указано в виде трех кортежей в формате(CHARSET, LANGUAGE, VALUE)
, гдеCHARSET
- это строка, обозначающая кодировку, которая будет использоваться для кодирования значения,LANGUAGE
обычно может быть присваивается значениеNone
или пустая строка (другие варианты смотрите в разделе RFC 2231), аVALUE
- это строковое значение, содержащее кодовые точки, отличные от ASCII. Если кортеж из трех элементов не передан и значение содержит символы, отличные от ASCII, оно автоматически кодируется в формате RFC 2231 с использованиемCHARSET
изutf-8
иLANGUAGE
изNone
.Вот пример:
msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')
Это добавит заголовок, который будет выглядеть следующим образом
Content-Disposition: attachment; filename="bud.gif"
Пример с символами, отличными от ASCII:
msg.add_header('Content-Disposition', 'attachment', filename=('iso-8859-1', '', 'Fußballer.ppt'))
Который производит
Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
- replace_header(_name, _value)¶
Замените заголовок. Замените первый заголовок, найденный в сообщении, который соответствует _name, сохранив порядок следования заголовков и регистр имен полей. Если соответствующий заголовок не найден, выводится значение
KeyError
.
- get_content_type()¶
Возвращает тип содержимого сообщения. Возвращаемая строка преобразуется в нижний регистр формы maintype/subtype. Если в сообщении не было заголовка Content-Type, будет возвращен тип по умолчанию, указанный в
get_default_type()
. Поскольку в соответствии с RFC 2045 сообщения всегда имеют тип по умолчанию,get_content_type()
всегда будет возвращать значение.RFC 2045 определяет тип сообщения по умолчанию как text/plain, если только оно не отображается внутри контейнера multipart/digest, в этом случае это будет message/rfc822. Если заголовок Content-Type содержит недопустимую спецификацию типа, RFC 2045 требует, чтобы типом по умолчанию был text/plain.
- get_content_maintype()¶
Возвращает основной тип содержимого сообщения. Это maintype часть строки, возвращаемая
get_content_type()
.
- get_content_subtype()¶
Возвращает тип вложенного содержимого сообщения. Это subtype часть строки, возвращаемая
get_content_type()
.
- get_default_type()¶
Возвращает тип содержимого по умолчанию. Большинство сообщений имеют тип содержимого по умолчанию text/plain, за исключением сообщений, которые являются подразделами контейнеров multipart/digest. Такие подразделы имеют тип содержимого по умолчанию message/rfc822.
- set_default_type(ctype)¶
Задайте тип содержимого по умолчанию. ctype должен быть либо text/plain, либо message/rfc822, хотя это не обязательно. Тип содержимого по умолчанию не сохраняется в заголовке Content-Type.
- get_params(failobj=None, header='content-type', unquote=True)¶
Возвращает параметры сообщения Content-Type в виде списка. Элементы возвращаемого списка представляют собой 2-кортежные пары ключ/значение, разделенные знаком
'='
. Левая часть'='
- это ключ, в то время как правая часть - это значение. Если в параметре нет знака'='
, то значением будет пустая строка, в противном случае значение будет таким, как описано в разделеget_param()
, и не будет заключено в кавычки, если необязательный параметр завершать кавычками равенTrue
(по умолчанию).Необязательный failobj - это объект, который возвращается, если нет заголовка Content-Type. Необязательный header - это заголовок для поиска вместо Content-Type.
Это устаревший метод. В классе
EmailMessage
его функциональность заменена свойством params отдельных объектов header, возвращаемых методами доступа к заголовку.
- get_param(param, failobj=None, header='content-type', unquote=True)¶
Возвращает значение параметра заголовка Content-Type param в виде строки. Если у сообщения нет заголовка Content-Type или если такой параметр отсутствует, то возвращается failobj (по умолчанию используется значение
None
).Необязательный заголовок, если указан, указывает заголовок сообщения, который следует использовать вместо Content-Type.
Ключи параметров всегда сравниваются без учета регистра. Возвращаемое значение может быть либо строкой, либо 3-кратным кортежем, если параметр был закодирован как RFC 2231. Когда это кортеж из 3 элементов, элементы значения имеют вид
(CHARSET, LANGUAGE, VALUE)
. Обратите внимание, что какCHARSET
, так иLANGUAGE
могут бытьNone
, и в этом случае вам следует учитывать, чтоVALUE
должен быть закодирован в кодировкеus-ascii
. Обычно вы можете проигнорироватьLANGUAGE
.Если вашему приложению безразлично, был ли параметр закодирован как в RFC 2231, вы можете свернуть значение параметра, вызвав
email.utils.collapse_rfc2231_value()
, передав возвращаемое значение изget_param()
. Это вернет соответствующим образом декодированную строку в Юникоде, если значение является кортежем, или исходную строку без кавычек, если это не так. Например:rawparam = msg.get_param('foo') param = email.utils.collapse_rfc2231_value(rawparam)
В любом случае значение параметра (либо возвращаемая строка, либо элемент
VALUE
в кортеже 3) всегда не заключено в кавычки, если только для параметра unquote не задано значениеFalse
.Это устаревший метод. В классе
EmailMessage
его функциональность заменена свойством params отдельных объектов header, возвращаемых методами доступа к заголовку.
- set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)¶
Задайте параметр в заголовке Content-Type. Если параметр уже существует в заголовке, его значение будет заменено на value. Если заголовок Content-Type для этого сообщения еще не определен, то для него будет установлено значение text/plain, а новое значение параметра будет добавлено в соответствии с RFC 2045.
Необязательный header указывает альтернативный заголовок Content-Type, и все параметры будут заключены в кавычки по мере необходимости, если только необязательный requote не равен
False
(по умолчанию используетсяTrue
).Если указан необязательный параметр charset, параметр будет закодирован в соответствии с RFC 2231. Необязательный параметр language указывает язык RFC 2231, по умолчанию используется пустая строка. Как charset, так и language должны быть строками.
Если значение replace равно
False
(по умолчанию), заголовок перемещается в конец списка заголовков. Если значение replace равноTrue
, заголовок будет обновлен на месте.Изменено в версии 3.4:
replace
добавлено ключевое слово.
- del_param(param, header='content-type', requote=True)¶
Полностью удалите данный параметр из заголовка Content-Type. Заголовок будет переписан без параметра или его значения. Все значения будут заключены в кавычки по мере необходимости, если только значение requote не равно
False
(по умолчанию используетсяTrue
). Необязательный заголовок указывает альтернативу Content-Type.
- set_type(type, header='Content-Type', requote=True)¶
Задайте основной тип и подтип для заголовка Content-Type. тип должен быть строкой в форме maintype/subtype, в противном случае будет выведен
ValueError
.Этот метод заменяет заголовок Content-Type, сохраняя все параметры на своих местах. Если requote равен
False
, это оставляет существующий заголовок без изменений, в противном случае параметры будут заключены в кавычки (по умолчанию).Альтернативный заголовок может быть указан в аргументе header. Когда задан заголовок Content-Type, также добавляется заголовок MIME-Version.
Это устаревший метод. В классе
EmailMessage
его функциональность заменена методамиmake_
иadd_
.
- get_filename(failobj=None)¶
Возвращает значение параметра
filename
в заголовке Content-Disposition сообщения. Если заголовок не содержит параметраfilename
, этот метод возвращается к поиску параметраname
в заголовке Content-Type. Если ни один из них не найден или заголовок отсутствует, то возвращается failobj. Возвращаемая строка всегда будет без кавычек в соответствии сemail.utils.unquote()
.
- get_boundary(failobj=None)¶
Возвращает значение параметра
boundary
заголовка Content-Type сообщения или failobj, если либо заголовок отсутствует, либо у него нет параметраboundary
. Возвращаемая строка всегда будет без кавычек в соответствии сemail.utils.unquote()
.
- set_boundary(boundary)¶
Установите для параметра
boundary
заголовка Content-Type значение boundary.set_boundary()
при необходимости всегда будет указывать boundary в кавычках.HeaderParseError
вызывается, если объект сообщения не имеет заголовка Content-Type.Обратите внимание, что использование этого метода немного отличается от удаления старого заголовка Content-Type и добавления нового с новой границей через
add_header()
, посколькуset_boundary()
сохраняет порядок заголовка Content-Type в список заголовков. Однако он не сохраняет никаких строк продолжения, которые могли присутствовать в исходном заголовке Content-Type.
- get_content_charset(failobj=None)¶
Возвращает параметр
charset
заголовка Content-Type, преобразованный в нижний регистр. Если нет заголовка Content-Type или если у этого заголовка нет параметраcharset
, возвращается failobj.Обратите внимание, что этот метод отличается от
get_charset()
, который возвращает экземплярCharset
для кодировки текста сообщения по умолчанию.
- get_charsets(failobj=None)¶
Возвращает список, содержащий названия наборов символов в сообщении. Если сообщение содержит multipart, то список будет содержать по одному элементу для каждой части полезной нагрузки, в противном случае это будет список длиной 1.
Каждый элемент в списке будет представлять собой строку, которая является значением параметра
charset
в заголовке Content-Type для представленного подраздела. Однако, если подраздел не имеет заголовка Content-Type, параметраcharset
или не имеет MIME-типа text main, то этим элементом в возвращаемом списке будет failobj.
- get_content_disposition()¶
Возвращает значение в нижнем регистре (без параметров) заголовка сообщения Content-Disposition, если он есть, или
None
. Возможными значениями для этого метода являются встроенный, вложенный илиNone
, если сообщение следует за RFC 2183.Добавлено в версии 3.5.
- walk()¶
Метод
walk()
- это универсальный генератор, который можно использовать для итерации по всем частям и подразделам дерева объектов сообщения в порядке прохождения в глубину. Обычно вы будете использоватьwalk()
в качестве итератора в циклеfor
; каждая итерация возвращает следующую подразделенную часть.Вот пример, который выводит MIME-тип каждой части структуры составного сообщения:
>>> for part in msg.walk(): ... print(part.get_content_type()) multipart/report text/plain message/delivery-status text/plain text/plain message/rfc822 text/plain
walk
выполняет итерацию по подразделам любой части, гдеis_multipart()
возвращаетTrue
, хотяmsg.get_content_maintype() == 'multipart'
может возвращатьFalse
. Мы можем увидеть это в нашем примере, используя вспомогательную функцию отладки_structure
:>>> for part in msg.walk(): ... print(part.get_content_maintype() == 'multipart', ... part.is_multipart()) True True False False False True False False False False False True False False >>> _structure(msg) multipart/report text/plain message/delivery-status text/plain text/plain message/rfc822 text/plain
Здесь
message
частями не являютсяmultiparts
, но они содержат подразделы.is_multipart()
возвращаетTrue
, аwalk
переходит в подразделы.
Message
объекты также могут дополнительно содержать два атрибута экземпляра, которые могут использоваться при генерации обычного текста MIME-сообщения.- preamble¶
Формат MIME-документа допускает наличие некоторого количества текста между пустой строкой, следующей за заголовками, и первой разделительной строкой, состоящей из нескольких частей. Обычно этот текст никогда не отображается в программе чтения почты с поддержкой MIME, поскольку он выходит за рамки стандартной защиты MIME. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в программе чтения, не поддерживающей MIME, этот текст может стать видимым.
Атрибут preamble содержит этот начальный дополнительный текст для MIME-документов. Когда
Parser
обнаруживает некоторый текст после заголовков, но перед первой строкой границы, он присваивает этот текст атрибуту preamble сообщения. КогдаGenerator
записывает обычное текстовое представление MIME-сообщения и обнаруживает, что у сообщения есть атрибут preamble, он записывает этот текст в область между заголовками и первой границей. Более подробную информацию смотрите в разделахemail.parser
иemail.generator
.Обратите внимание, что если объект message не имеет преамбулы, атрибутом preamble будет
None
.
- epilogue¶
Атрибут epilogue действует так же, как и атрибут preamble, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения.
Вам не нужно устанавливать в качестве эпилога пустую строку для того, чтобы
Generator
выводил новую строку в конце файла.
- defects¶
Атрибут defects содержит список всех проблем, обнаруженных при разборе этого сообщения. Подробное описание возможных ошибок разбора приведено в разделе
email.errors
.