import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart class Template(object): html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{Title}</title> </head> <body> <div style="color: red; font-size: 16px;">{Content}</div> <div>bye bye</div> </body> </html> """ def __init__(self, **kwargs): self.kwargs = kwargs def simple_render(self): return self.html.format(**self.kwargs) class EmailSender(object): def __init__(self, from_address, password, smtp_host, smtp_port, ssl=False, template:Template=None): self.address = from_address self.password = password self.smtp_host = smtp_host self.smtp_port = smtp_port self.ssl = ssl self.connected = False self.template = template self.init_client() def create_attachment(self, filename=None, filepath=None, stream=None, charset='utf-8'): """ 创建附件 :param filename: :param filepath: :param stream: :param charset: :return: """ assert any((filepath, stream)), "attachment must provide filepath or file" assert filename, "filename can not be None" if filepath: f = open(filepath, 'rb') stream = f.read() f.close() attachment = MIMEText(stream, 'base64', charset) attachment["Content-Type"] = "application/octet-stream" attachment["Content-Disposition"] = f"attachment; filename={filename}" return attachment def init_client(self): """ 初始化客户端 :return: """ if self.ssl: self.client = smtplib.SMTP_SSL() else: self.client = smtplib.SMTP() try: self.client.connect(self.smtp_host, self.smtp_port) self.client.login(self.address, self.password) self.connected = True except smtplib.SMTPAuthenticationError: print("username or password wrong.") except smtplib.SMTPHeloError: print("server didnt reply.") except smtplib.SMTPException as e: print(e) def create_text_or_html(self, text, is_html=True, charset=None): """ 创建email信件内容 :param text: :param is_html: :param charset: :return: """ sub_type = "html" if is_html else "plain" message = MIMEText(text, sub_type, charset) return message def send_with_attachment(self, Subject, attachment, sender, receiver, to_address): """ attachment: {"filename": filename, "stream": file stream, "filepath": file path} must provide at least one of filepath & stream """ message = MIMEMultipart() message["From"] = sender message["To"] = receiver message["Subject"] = Subject message.attach(self.create_text_or_html(self.template.simple_render())) message.attach(self.create_attachment(**attachment)) self.client.sendmail(self.address, to_address, message.as_string()) if __name__ == '__main__': my_address = "[email protected]" password = "PASSWORD" to_address = "[email protected]" email_smtp = "smtp.126.com" context = "一对测试的内容" template = Template(Content="测试内容,传递一个附件", Title="测试") sender = EmailSender(my_address, password, email_smtp, 25, template=template) sender.send_with_attachment('邮件测试', {"filename": "example.xls", "filepath": r"C:\Users\Haiton\Desktop\name_list.xls"}, "126.com", "qq.com", to_address)标签:发邮件,python,self,smtp,filename,attachment,版本,address,message From: https://www.cnblogs.com/haiton/p/17081890.html