Python自动化邮件发送类深度解析
一、类结构设计与初始化方法
1.1 类定义与参数说明
class Email :
def __init__ ( self,
sender: str ,
receiver: [ str , list ] ,
title: str ,
server: str ,
auth_code: str ,
message: str = None ,
attachment_file: [ str , list ] = None ) :
参数验证逻辑表
参数 类型 必需性 示例值 sender str 是 “user@qq.com” receiver str/list 是 [“user1@qq.com”, …] auth_code str 是 “xwjfghxcz…” server str 是 “smtp.qq.com”
二、核心方法实现解析
2.1 邮件发送主流程
def send ( self) :
self. msg[ 'Subject' ] = self. title
self. msg[ 'From' ] = self. sender
self. msg[ 'To' ] = ', ' . join( self. receiver) if isinstance ( self. receiver, list ) else self. receiver
if self. message:
self. msg. attach( MIMEText( self. message, 'html' if '<html>' in self. message else 'plain' ) )
if self. attachment_file: . . .
smtp_server = SMTP( self. server)
smtp_server. login( self. sender, self. auth_code)
smtp_server. sendmail( . . . )
smtp_server. quit( )
2.2 附件处理机制
def _attach_file ( self, file_path) :
if not exists( file_path) :
raise FileNotFoundError( . . . )
with open ( file_path, 'r' , encoding= 'utf-8' ) as f:
att = MIMEText( f. read( ) , 'plain' , 'utf-8' )
att[ 'Content-Type' ] = 'application/octet-stream'
file_name = re. split( r'[\\|/]' , file_path) [ - 1 ]
att[ 'Content-Disposition' ] = f'attachment; filename=" { file_name} "'
self. msg. attach( att)
支持的文件类型
文件类型 处理方式 限制条件 .txt/.log 直接读取 需UTF-8编码 .csv/.json 同文本文件 内容需为文本格式 二进制文件 当前不支持 会引发解码错误
三、完整使用示例
3.1 测试报告发送场景
report_email = Email(
sender= 'tester@qq.com' ,
receiver= [ 'manager@qq.com' , 'dev_team@qq.com' ] ,
title= '[自动化测试报告] 2024-01-01' ,
server= 'smtp.qq.com' ,
auth_code= 'xwjfghxcz...' ,
message= '''
<html>
<body>
<h2>测试执行概要</h2>
<p>成功率:<span style="color:green">95%</span></p>
<p>详细报告请查看附件</p>
</body>
</html>
''' ,
attachment_file= [
r'E:\reports\test_result_20240101.html' ,
r'E:\logs\execution.log'
]
)
try :
report_email. send( )
print ( "✅ 测试报告邮件发送成功" )
except Exception as e:
print ( f"❌ 邮件发送失败: { str ( e) } " )
3.2 实际输出效果
✅ 测试报告邮件发送成功
收件箱显示效果
发件人: tester@qq.com
主题: [自动化测试报告] 2024-01-01
正文:
测试执行概要
成功率:95%
详细报告请查看附件
附件:
test_result_20240101.html (1.2MB)
execution.log (350KB)
四、代码优化建议
4.1 现存问题清单
问题描述 风险等级 改进方案 附件仅支持文本文件 高 添加二进制文件处理逻辑 未实现SSL加密传输 高 使用SMTP_SSL类替代SMTP 缺乏重试机制 中 添加失败重试逻辑(最多3次) 收件人列表处理不完善 低 统一转换为列表格式处理
4.2 增强型附件处理
from email. mime. application import MIMEApplication
def _attach_file ( self, file_path) :
with open ( file_path, 'rb' ) as f:
att = MIMEApplication( f. read( ) )
att. add_header( 'Content-Disposition' , 'attachment' ,
filename= ( 'utf-8' , '' , file_name) )
4.3 企业级最佳实践
某大厂邮件服务规范要求 :
敏感信息(授权码)必须通过环境变量传递 所有邮件必须包含退订链接(法律合规) 附件大小超过10MB需使用云存储链接替代 必须记录邮件发送日志(含时间戳和收件人哈希值) 实施速率限制(每分钟最多发送10封)
import os
from hashlib import md5
auth_code = os. getenv( 'SMTP_AUTH_CODE' )
def send ( self) :
. . .
log_msg = f"[ { datetime. now( ) } ] Sent to { md5( receiver. encode( ) ) . hexdigest( ) } "
logging. info( log_msg)
五、完整代码
from email. mime. multipart import MIMEMultipart
from email. mime. text import MIMEText
from os. path import exists
import re
from smtplib import SMTP
class Email :
def __init__ ( self,
sender: str ,
receiver: [ str , list ] ,
title: str ,
server: str ,
auth_code: str ,
message: str = None ,
attachment_file: [ str , list ] = None ) :
self. sender = sender
self. receiver = receiver
self. title = title
self. message = message
self. attachment_file = attachment_file
self. server = server
self. auth_code = auth_code
self. msg = MIMEMultipart( 'related' )
def send ( self) :
self. msg[ 'Subject' ] = self. title
self. msg[ 'From' ] = self. sender
self. msg[ 'To' ] = self. receiver
if self. message:
self. msg. attach( MIMEText( self. message) )
if self. attachment_file:
if isinstance ( self. attachment_file, str ) :
self. _attach_file( self. attachment_file)
if isinstance ( self. attachment_file, list ) :
for _path in self. attachment_file:
self. _attach_file( _path)
smtp_server = SMTP( self. server)
smtp_server. login( self. sender, self. auth_code)
smtp_server. sendmail( self. sender, self. receiver, self. msg. as_string( ) )
smtp_server. quit( )
def _attach_file ( self, file_path) :
if not exists( file_path) :
raise FileNotFoundError( f' { file_path} :附件文件不存在或者附件文件路径' )
with open ( file_path, 'r' , encoding= 'utf-8' ) as f:
att = MIMEText( f. read( ) , 'plain' , 'utf-8' )
att[ 'Content-Type' ] = 'application/octet-stream'
file_name = re. split( r'[\\|/]' , file_path) [ - 1 ]
att[ 'Content-Disposition' ] = f'attachment; filename=" { file_name} "'
self. msg. attach( att)
email = Email( sender= 'xxx@qq.com' ,
receiver= 'xxx@qq.com' ,
title= 'title' ,
server= 'smtp.qq.com' ,
auth_code= 'xxxxxx' ,
message= 'xxxxx' ,
attachment_file= 'E:\\Py3Sel3Ifram\\report.html'
)
「小贴士」 :点击头像→【关注 】按钮,获取更多软件测试的晋升认知不迷路! 🚀