Почему нужны две переменные и что происходит в данной строчке кода?

Я решаю свою задачку, используя Python 3.11 Работаю с библиотекой imaplib. Подключаюсь к mail.ru

Получаю письмо и извлекаю часть информации о нём Зная номер письма, я его получаю следующим способом.

res, msg = imap.fetch(b'19', '(RFC822)')  #Для метода search по порядковому номеру письма
res, msg = imap.uid('fetch', b'28', '(RFC822)')  #Для метода uid

Я хотел разобраться досконально, что происходит в любой из этих строчек.

Для меня было непонятно, почему используются две переменные для одного или друго выражения. Так и не понял. Сперва подумал, что это потому, что возвращаемый тип данных у одного или другого выражения - tuple. Но кортежи могут храниться и в одной переменной, потому вопрос все еще остается.

Если убрать одну переменную, то будет ошибка.

AttributeError: 'str' object has no attribute 'decode'. Did you mean: 'encode'?

Весь код выглядит так:

import imaplib
import email
from email.header import decode_header
from configparser import ConfigParser

urlsconf ='config/config.ini'
config =ConfigParser() 
config.read(urlsconf) 

mail_pass = config['login_mail_ru']['mail_pass'] 
username = config['login_mail_ru']['username']
imap_server = "imap.mail.ru"
imap = imaplib.IMAP4_SSL(imap_server)
print(imap.login(username, mail_pass))
sent_emails = (imap.select(b"&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-"))
count_mails = int(sent_emails[1][0].decode("utf-8"))
print(count_mails)

res, msg = imap.fetch(f'20'.encode(), '(RFC822)')  
msg = email.message_from_bytes(msg[0][1]) # Извлекаем часть с содержанием
letter_subject = msg["Subject"] # Извлекаем тему сообщения в кодеровке
subject = decode_header(letter_subject)[0][0].decode() # Декодируем в текст
first_word_subject = subject[:subject.find(" ")] # Вырезаем первое слово из содержания
print(first_word_subject)

Расскажите, пожалуйста, почему нужно использовать две переменные и что происходит в данной строчке?


Ответы (1 шт):

Автор решения: Алексей Р

Метод fetch() возвращает кортеж -

IMAP4.fetch(message_set, message_parts) Fetch (parts of) messages. message_parts should be a string of message part names enclosed within parentheses, eg: "(UID BODY[TEXT])". Returned data are tuples of message part envelope and data.

Действительно, этот кортеж можно занести в одну переменную и использовать с индексами:

result = imap.fetch(...)
print(result[0])
txt = result[1]

Очевидно, что при таком подходе удобство ниже - вместо осмысленных имен переменных - индексы. Можно сделать по-другому:

result = imap.fetch(...)
envelope = result[0]
print(envelope)
txt = result[1]

и далее оперировать переменными с осмысленными именами, но получается громоздко. Удобства добавляет распаковка:

res, msg = imap.fetch(...)
# или, нагляднее:
res, msg = (envelop,data)

то есть двум переменным за одну операцию присваиваются соответствующие значения из кортежа. Думаю, что это делается, как отметил в комментарии @strawdog, для удобства, а также для исключения ошибок, связанных с применением индексов (невнимательность, например).

→ Ссылка