将附件附加到电子邮件时出现 KeyError

Getting a KeyError when attaching attachments to an email

所以我正在尝试创建一个自动电子邮件脚本,用于读取姓氏、收件人电子邮件和要从 excel 文件中附加的文件。

出于某种原因,当我发送带有附件的电子邮件时 returns 一个 KeyError,我认为这可以追溯到我正在使用的附件文件名的占位符 .add_header('Content-Disposition', 'attachment; filename = {file}')和。因为每当我更改占位符时,KeyError 指定我在其中写入的内容。

无论如何,这是源代码

import pandas as pd
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

context = ssl.create_default_context()

sender = 'john@email.com'
sender_pass = '123456789'
email_subject = 'subject'
attachments_list = 'testingemail.xlsx'

body = 'Dear Mx. {surname} body'
    
def attach_attachment(attachment_list, payload):

    # opening excel file into dataframe
    attachments = pd.read_excel(attachment_list, sheet_name = 'attachments')

    for file in attachments['attachments']:
        with open(file, 'rb') as attachment:
            part = MIMEBase('application', 'octet-stream')
            part.set_payload((attachment).read())

        encoders.encode_base64(part) # encoding attachment
        part.add_header(
            'Content-Disposition',
            'attachment; filename = {file}',
        )          

        # attaching attachment
        payload.attach(part)      

def composing_email(e_sender, e_password, e_subject, e_recipient, attachment_list):
    # setup the MIME
    message = MIMEMultipart()
    message['From'] = e_sender
    message['To'] = e_recipient
    message['Subject'] = e_subject

    # attaching body and the attachments for the mail
    message.attach(MIMEText(body, 'plain'))
    attach_attachment(attachment_list, message)
    
    # create SMTP session for sending the mail
    session = smtplib.SMTP('smtp.gmail.com', 587) # gmail port
    session.starttls(context = context) # securing connection
    session.login(e_sender, e_password) # logging into account

    text = message.as_string()

    # actually sending shit
    session.sendmail(e_sender, 
                    e_recipient, 
                    text.format(surname = surname, 
                                receiver_email = recipient, 
                                sender = e_sender,
                                )
                    )

    session.quit()
    print('Mail successfully sent to {surname} with emal {recipient}')
   

if __name__ == '__main__':
    surname_email = pd.read_excel('testingemail.xlsx', sheet_name = 'surname_email')
    for surname, recipient in surname_email.itertuples(index=False):
        composing_email(sender, sender_pass, email_subject, recipient, attachments_list)
  

这是错误

Traceback (most recent call last):
  File "c:\Users\zddj9\Desktop\auto_email\script.py", line 77, in <module>
    composing_email(sender, sender_pass, email_subject, recipient, attachments_list)
  File "c:\Users\zddj9\Desktop\auto_email\script.py", line 64, in composing_email
    text.format(surname = surname,
KeyError: 'file'

我刚刚意识到我需要使用 f-string 格式

而不是这个

part.add_header(
            'Content-Disposition',
            'attachment; filename = {file}',
        )          

在带有占位符

的参数前添加一个f
part.add_header(
            'Content-Disposition',
            f'attachment; filename = {file}',
        )          

如果没有 f-string 格式

,确认也不会起作用
print('Mail successfully sent to {surname} with email {recipient}')

应该是这个

print(f'Mail successfully sent to {surname} with email {recipient}')