使用Python实现发送Email电子邮件【第19篇—python发邮件】
文章目录
- 👽使用Python实现发送Email电子邮件
 - 🎶实现原理
 - 🏃Python实现发送Email电子邮件-基础版
 - 👫实现源码
 - 🙆源码解析
 
- 💇Python实现发送Email电子邮件-完善版
 - 👫实现源码
 - 🙆源码解析
 - 🙀优化
 
- 👥总结
 
👽使用Python实现发送Email电子邮件
🎶实现原理

-  
导入必要的模块:
- 导入
smtplib用于处理 SMTP 功能的模块,以及从email模块导入构建电子邮件消息所需的各个组件。 
 - 导入
 -  
定义
send_email函数:- 创建一个名为 
send_email的函数,该函数接受 SMTP 服务器详细信息、发件人和收件人信息、主题、内容和附件等参数。 
 - 创建一个名为 
 -  
格式化发件人地址:
- 实现 
_format_addr函数以正确格式化发件人的电子邮件地址,如果提供了显示名称,则包含在内。 
 - 实现 
 -  
初始化电子邮件消息对象:
- 创建 
MIMEMultipart的实例,它将作为电子邮件消息的容器。 
 - 创建 
 -  
设置发件人信息:
- 在电子邮件消息中设置发件人的信息,包括如果提供了发件人名称则进行设置。
 
 -  
设置收件人信息:
- 在电子邮件消息中设置收件人的信息。
 
 -  
处理抄送(CC)信息:
- 如果在 CC 列表中有收件人,则相应地更新电子邮件消息。
 
 -  
处理密送(BCC)信息:
- 如果在 BCC 列表中有收件人,则类似于处理 CC 列表。
 
 -  
设置主题和内容:
- 在电子邮件消息中设置主题和内容。
 
 -  
处理附件:
- 遍历附件列表,读取每个文件,确定其 MIME 类型,并将其附加到电子邮件消息中。
 
 -  
尝试连接到 SMTP 服务器并发送电子邮件:
- 尝试使用提供的凭据连接到指定的 SMTP 服务器。
 - 如果连接成功,则使用用户名和密码进行登录。
 - 使用 
sendmail方法将电子邮件发送给指定的收件人。 - 关闭与 SMTP 服务器的连接。
 
 -  
处理异常:
- 实现异常处理以处理在过程中可能发生的错误,例如文件未找到、附件读取失败或电子邮件发送失败。
 
 
该实现涉及使用 email 模块创建电子邮件消息,处理发件人和收件人信息,添加附件,并使用 smtplib 模块连接到 SMTP 服务器并发送电子邮件。代码被组织成一个函数,以便实现可重用性和清晰度。

🏃Python实现发送Email电子邮件-基础版
👫实现源码
# 导入smtplib模块,这个模块是Python的标准库,用于发送电子邮件
import smtplib# 从email模块中导入MIMEText类,这个类用于创建文本邮件的MIME消息对象
from email.mime.text import MIMEText# 定义一个变量,存储QQ邮箱的SMTP服务器授权码,此授权码用于登录QQ邮箱SMTP服务器
secretPass = 'xxxxxxxxxxxxxxxxxx'  # SMTP服务器授权码# 定义一个函数,用于发送指定邮箱的邮件
def sendqqmail(sender_email, sender_pass, rec_email, subject, message):# 使用MIMEText类创建一个邮件消息对象,其中message参数是邮件的内容msg = MIMEText(message)# 设置邮件的主题msg['Subject'] = subject# 设置邮件的发件人邮箱msg['From'] = sender_email# 设置邮件的收件人邮箱msg['To'] = rec_email# 使用smtplib模块的SMTP_SSL类创建一个SSL连接对象,连接到QQ邮箱SMTP服务器,其中'smtp.qq.com'是SMTP服务器地址,465是端口号# 在这个类中,有两个方法login和send_message,分别用于登录和发送邮件with smtplib.SMTP_SSL('smtp.qq.com', 465) as smtp:# 使用login方法登录SMTP服务器,参数sender_email和sender_pass分别是发件人的邮箱地址和授权码smtp.login(sender_email, sender_pass)# 如果登录成功,打印一条消息print('登录邮箱成功!')# 使用send_message方法发送邮件,参数msg是要发送的邮件消息对象smtp.send_message(msg)# 发送成功后,打印一条消息print('邮件发送完毕')# 关闭SMTP服务连接smtp.quit()# 定义一个主函数,用于运行整个程序
def main():# 定义发件人的邮箱地址sender_email = 'xxxxxxxxx@qq.com'  # 发信人邮箱# 定义发件人的邮箱授权码emailpass = secretPass  # 邮箱授权码# 定义收件人的邮箱地址to_email = 'xxxxxx@xxx.com'  # 收信人邮箱# 定义邮件的主题sub_msg = '测试python发送邮件'  # 邮件主题# 定义邮件的正文内容content = '这是我的第一个python发送邮件测试'  # 邮件正文内容# 调用sendqqmail函数,发送邮件sendqqmail(sender_email, emailpass, to_email, sub_msg, content)  # 发送邮件# 执行main函数,这是Python的标准模式
if __name__ == '__main__':main()
 
🙆源码解析
通过SMTP协议发送邮件。
- 导入必要的模块: 
smtplib: 用于连接SMTP服务器并发送邮件。MIMEText类:用于创建文本邮件的MIME消息对象。
 
import smtplib
from email.mime.text import MIMEText
 
- 定义了一个QQ邮箱的SMTP服务器授权码:
 
secretPass = 'xxxxxxxxxxxxxxxxxx'  # SMTP服务器授权码
 
- 定义了一个函数 
sendqqmail,用于发送指定邮箱的邮件:- 创建
MIMEText对象,设置邮件主题、发件人、收件人以及邮件内容。 - 使用
smtplib.SMTP_SSL创建一个SSL连接对象,连接到QQ邮箱SMTP服务器。 - 使用
login方法登录SMTP服务器。 - 使用
send_message方法发送邮件。 - 打印登录成功和邮件发送完毕的消息,然后关闭SMTP服务连接。
 
 - 创建
 
def sendqqmail(sender_email, sender_pass, rec_email, subject, message):# ...(略)
 
- 定义了主函数 
main:- 定义发件人、邮箱授权码、收件人、邮件主题和邮件内容。
 - 调用 
sendqqmail函数发送邮件。 
 
def main():# ...(略)
 
- 使用 
if __name__ == '__main__':来确保代码在作为脚本直接运行时才会执行main函数。 
if __name__ == '__main__':main()
 
注意事项:
- 请谨慎存储和处理邮箱密码或授权码,不要将其硬编码在代码中或分享给其他人。
 - 在使用SMTP服务发送邮件时,需要确保你的邮箱开启了SMTP服务,并使用了正确的SMTP服务器地址和端口号。这些信息可以从你的邮箱服务提供商获取。
 
💇Python实现发送Email电子邮件-完善版
👫实现源码
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import parseaddr, formataddr
import mimetypes
import os def send_email(smtp_server, username, password, sender, recipients, subject, content, cc, bcc, port=25, sendername=None, attachments=None):def _format_addr(s):name, addr = parseaddr(s)return formataddr((Header(name, 'utf-8').encode(), addr))if not attachments:attachments = []msg = MIMEMultipart()if sendername:msg['From'] = _format_addr(sendername + ' <%s>' % sender)else:msg['From'] = senderif isinstance(recipients, str):recipients = [recipients]msg['To'] = ",".join(recipients)if cc:if isinstance(cc, str):cc = [cc]cc_list = [addr for addr in cc if addr not in recipients]if cc_list:msg['Cc'] = ",".join(cc_list)recipients += cc_listif bcc:if isinstance(bcc, str):bcc = [bcc]bcc_list = [addr for addr in bcc if addr not in recipients]if bcc_list:msg['Bcc'] = ",".join(bcc_list)recipients += bcc_listmsg['Subject'] = Header(subject, 'utf-8').encode()text_part = MIMEText(content, 'html', 'utf-8')msg.attach(text_part)for attachment in attachments:file_path = attachment["path"]if not os.path.isfile(file_path):print("附件文件不存在:{}".format(file_path))continuetry:with open(file_path, "rb") as f:mime_type, encoding = mimetypes.guess_type(file_path)if mime_type is None:mime_type = 'application/octet-stream'part = MIMEApplication(f.read())part.add_header('Content-Disposition', 'attachment', filename=attachment["filename"])part.add_header('Content-Type', mime_type)msg.attach(part)except FileNotFoundError as e:print("文件未找到:{}".format(e))except Exception as e:print("附件读取失败:{}".format(e))try:if str(port) == "25":server = smtplib.SMTP(smtp_server, port)else:server = smtplib.SMTP_SSL(smtp_server, port)server.login(username, password)server.sendmail(sender, recipients, msg.as_string())server.quit()print("邮件发送成功!")except Exception as e:print("邮件发送失败:{}".format(e))smtp_server = "smtp.aliyun.com"
username = "abc@aliyun.com"
password = "password"
sender = "abc@aliyun.com"
recipients = "abc@abc.cn"
cc = ["abc@126.com","abc@139.com"]
bcc = ""
subject = "title"
content = "content"
n = "name"
port = 25
attachments = [{"filename":"申请单.xlsx","path":"C:/申请单.xlsx"},{"filename": "新课标.docx", "path": "D:/新课标.docx"},{"filename": "笨笨狗.pdf", "path": "D:/books/笨笨狗.pdf"}]send_email(smtp_server, username, password, sender, recipients, subject, content, cc,bcc,port=port, sendername=n, attachments=attachments)
 
🙆源码解析
用于发送带附件的邮件的 Python 脚本。
- 导入必要的模块: 
smtplib: 用于连接SMTP服务器并发送邮件。MIMEText:创建文本邮件的MIME消息对象。MIMEMultipart:创建包含附件的MIME消息对象。MIMEApplication:用于处理附件的MIME消息对象。Header:用于对邮件头进行编码。parseaddr和formataddr:用于格式化发件人和收件人地址。mimetypes:用于猜测文件的MIME类型。os:用于处理文件路径。
 
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import parseaddr, formataddr
import mimetypes
import os
 
- 定义了一个发送邮件的函数 
send_email:- 使用 
MIMEMultipart创建一个包含附件的邮件消息对象。 - 格式化发件人和收件人地址。
 - 设置邮件主题、发件人、收件人、抄送、密送。
 - 将文本内容添加到邮件中。
 - 添加附件到邮件中。
 - 使用 
smtplib连接到SMTP服务器,登录,发送邮件,然后关闭连接。 
 - 使用 
 
def send_email(smtp_server, username, password, sender, recipients, subject, content, cc, bcc, port=25, sendername=None, attachments=None):# ...(略)
 
- 定义了一个辅助函数 
_format_addr用于格式化地址: 
def _format_addr(s):name, addr = parseaddr(s)return formataddr((Header(name, 'utf-8').encode(), addr))
 
- 调用 
send_email函数发送邮件,传递了一些必要的参数,包括SMTP服务器、发件人、收件人、邮件主题、文本内容、抄送、密送、发件人姓名、附件等信息。 
smtp_server = "smtp.aliyun.com"
username = "abc@aliyun.com"
password = "password"
sender = "abc@aliyun.com"
recipients = "abc@abc.cn"
cc = ["abc@126.com","abc@139.com"]
bcc = ""
subject = "title"
content = "content"
n = "name"
port = 25
attachments = [{"filename":"申请单.xlsx","path":"C:/申请单.xlsx"},{"filename": "新课标.docx", "path": "D:/新课标.docx"},{"filename": "笨笨狗.pdf", "path": "D:/books/笨笨狗.pdf"}]send_email(smtp_server, username, password, sender, recipients, subject, content, cc,bcc,port=port, sendername=n, attachments=attachments)
 
🙀优化
第二段代码相对于第一段代码进行了一些优化,主要体现在以下几个方面:
-  
支持附件:
- 第二段代码引入了 
email.mime.multipart和email.mime.application模块,允许通过attachments参数添加附件。这使得邮件可以携带更多类型的内容。 
 - 第二段代码引入了 
 -  
更灵活的邮件构建:
- 第二段代码使用 
MIMEMultipart对象创建邮件消息,可以更灵活地构建邮件内容,包括添加文本部分、HTML部分、以及附件等。 
 - 第二段代码使用 
 -  
更友好的发件人地址:
- 引入了 
_format_addr辅助函数,用于格式化发件人地址,支持设置发件人姓名。 
 - 引入了 
 -  
更丰富的邮件头信息:
- 使用 
Header对邮件主题进行编码,确保支持非ASCII字符的主题。 - 设置了 
Content-Disposition头部,用于指定附件的处理方式。 
 - 使用 
 -  
更全面的错误处理:
- 添加了对附件文件是否存在的检查,并输出相应的错误信息。
 - 在捕获异常时,输出更详细的错误信息,有助于定位问题。
 
 -  
端口号处理:
- 第二段代码通过 
str(port) == "25"的判断来决定使用普通 SMTP 还是 SMTP_SSL,使得端口的设置更加直观。 
 - 第二段代码通过 
 -  
更清晰的代码结构:
- 第二段代码通过将不同的功能块划分为函数,使得代码结构更加清晰,方便维护和阅读。
 
 
第二段代码在邮件功能的实现上更为完善,具有更多的灵活性和可读性,并且考虑到了更多的错误处理情况,使得代码更健壮。
👥总结
这两段代码都是用于发送邮件的简单Python脚本,但第二段代码相对于第一段代码进行了一些优化和改进。以下是一些心得总结:
-  
支持附件的扩展: 第二段代码引入了附件的支持,使用了
email.mime.multipart和email.mime.application模块,使得邮件可以携带更多类型的内容,包括文本和附件。 -  
更友好的发件人地址: 引入了
_format_addr辅助函数,用于格式化发件人地址,支持设置发件人姓名。这样可以使邮件中的发件人信息更加友好和易读。 -  
更丰富的邮件头信息: 使用
Header对邮件主题进行编码,确保支持非ASCII字符的主题。同时,设置了Content-Disposition头部,用于指定附件的处理方式,提高邮件的兼容性。 -  
更全面的错误处理: 第二段代码在处理附件时增加了对附件文件是否存在的检查,并在捕获异常时输出更详细的错误信息。这样的改进有助于提高代码的健壮性,及时发现并处理潜在问题。
 -  
更清晰的代码结构: 第二段代码通过将不同功能块划分为函数,使得代码结构更清晰。这有助于提高代码的可读性和维护性,使每个功能单元更容易理解和修改。
 
总的来说,第二段代码在功能实现上更为完善,具有更多的灵活性和可读性,并且考虑到了更多的错误处理情况,使得代码更加健壮。在编写邮件发送脚本时,综合考虑邮件内容的复杂性和错误处理的全面性是很重要的。
相关文章:
使用Python实现发送Email电子邮件【第19篇—python发邮件】
文章目录 👽使用Python实现发送Email电子邮件🎶实现原理🏃Python实现发送Email电子邮件-基础版👫实现源码🙆源码解析 💇Python实现发送Email电子邮件-完善版👫实现源码🙆源码解析&am…...
Docker基本命令和Docker怎么自己制作镜像
基本命令 启动新的容器(指定容器名称和端口映射【主机端口:容器端口】) docker run --name 容器名 -p 8080:80 镜像名 启动新的容器(交互式) docker run -it centos7-with-jdk /bin/bash 特权方式启动容器 docker run -d --…...
Netty-2-数据编解码
解析编解码支持的原理 以编码为例,要将对象序列化成字节流,你可以使用MessageToByteEncoder或MessageToMessageEncoder类。 这两个类都继承自ChannelOutboundHandlerAdapter适配器类,用于进行数据的转换。 其中,对于MessageToMe…...
伽马校正:FPGA
参考资料: Tone Mapping 与 Gamma Correction - 知乎 (zhihu.com) Book_VIP: 《基于MATLAB与FPGA的图像处理教程》此书是业内第一本基于MATLAB与FPGA的图像处理教程,第一本真正结合理论及算法加速方案,在Matlab验证,以及在FPGA上…...
【SpringCloud笔记】(8)服务网关之GateWay
GateWay 概述简介 官网地址: 上一代网关Zuul 1.x:https://github.com/Netflix/zuul/wiki(有兴趣可以了解一下) gateway:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/…...
Compose常用布局
Compose布局基础知识 上一节对Compose做了简单的介绍,本章节主要介绍Compose中常用的布局,其中包括三个基础布局(Colmun、Row、Box);以及其他常用布局(ConstraintLayout 、BoxWithConstraints、HorizontalP…...
使用keytool查看Android APK签名
文章目录 一、找到JDK位置二、使用方法2.1 打开windows命令行工具2.2 查看签名 三、如何给APK做系统签名呢? 一、找到JDK位置 安卓AS之后,可选择继续安装JDK,如本文使用amazon版本默认位置:C:\Users\66176.jdks\corretto-1.8.0_342可通过自…...
数据库学习日常案例20231221-oracle libray cache lock分析
1 问题概述: 阻塞的源头为两个ddl操作导致大量的libray cache lock 其中1133为gis sde的create table as语句。 其中697为alter index语句。...
【数据结构】最短路径算法实现(Dijkstra(迪克斯特拉),FloydWarshall(弗洛伊德) )
文章目录 前言一、Dijkstra(迪克斯特拉)1.方法:2.代码实现 二、FloydWarshall(弗洛伊德)1.方法2.代码实现 完整源码 前言 最短路径问题:从在带权有向图G中的某一顶点出发,找出一条通往另一顶点…...
算法模板之队列图文详解
🌈个人主页:聆风吟 🔥系列专栏:算法模板、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. ⛳️模拟队列1.1 🔔用数组模拟实现队列1.1.1 👻队列的定…...
[node]Node.js 中REPL简单介绍
[node]Node.js 中REPL简单介绍 什么是REPL为什么使用REPL如何使用REPL 命令REPL模式node的全局内容展示node全局所有模块查看全局模块具体内容其它命令 实践 什么是REPL Node.js REPL(Read Eval Print Loop:交互式解释器) 表示电脑的环境,类似 Windows 系统的终端或…...
AtomHub 开源容器镜像中心开放公测,国内服务稳定下载
由开放原子开源基金会主导,华为、浪潮、DaoCloud、谐云、青云、飓风引擎以及 OpenSDV 开源联盟、openEuler 社区、OpenCloudOS 社区等成员单位共同发起建设的 AtomHub 可信镜像中心正式开放公测。AtomHub 秉承共建、共治、共享的理念,旨在为开源组织和开…...
java8实战 lambda表达式、函数式接口、方法引用双冒号(中)
前言 书接上文,上一篇博客讲到了lambda表达式的应用场景,本篇接着将java8实战第三章的总结。建议读者先看第一篇博客 其他函数式接口例子 上一篇有讲到Java API也有其他的函数式接口,书里也举了2个例子,一个是java.util.functi…...
FPGA高端项目:UltraScale GTH + SDI 视频编解码,SDI无缓存回环输出,提供2套工程源码和技术支持
目录 1、前言免责声明 2、相关方案推荐我这里已有的 GT 高速接口解决方案我目前已有的SDI编解码方案 3、详细设计方案设计框图3G-SDI摄像头LMH0384均衡EQUltraScale GTH 的SDI模式应用UltraScale GTH 基本结构参考时钟的选择和分配UltraScale GTH 发送和接收处理流程UltraScale…...
为什么react call api in cDidMount
为什么react call api in cDM 首先,放到constructor或者cWillMount不是语法错误 参考1 参考2 根据上2个参考,总结为: 1、官网就是这么建议的: 2、17版本后的react 由于fiber的出现导致 cWM 会调用多次! cWM 方法已…...
openGauss学习笔记-171 openGauss 数据库运维-备份与恢复-导入数据-深层复制
文章目录 openGauss学习笔记-171 openGauss 数据库运维-备份与恢复-导入数据-深层复制171.1 使用CREATE TABLE执行深层复制171.1.1 操作步骤 171.2 使用CREATE TABLE LIKE执行深层复制171.2.1 操作步骤 171.3 通过创建临时表并截断原始表来执行深层复制171.3.1 操作步骤 openGa…...
[kubernetes]控制平面ETCD
什么是ETCD CoreOS基于Raft开发的分布式key-value存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)etcd像是专门为集群环境的服务发现和注册而设计,它提供了数据TTL失效、数据改变监视、多值、目录监听、…...
序列化类的高级用法
1.3.3 模型类序列化器 如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。 ModelSerializer与常规的Serializer相同,但提供了: 基于模型类自动生成一系列…...
4.svn版本管理工具使用
1. 什么是SVN 版本控制 它可以记录每一次文件和目录的修改情况,这样就可以借此将数据恢复到以前的版本,并可以查看数据的更改细节! Subversion(简称SVN)是一个自由开源的版本控制系统。在Subversion管理下,文件和目录可以超越时空 SVN的优势 统一的版本号 Subversi…...
ZKP Algorithms for Efficient Cryptographic Operations 1 (MSM Pippenger)
MIT IAP 2023 Modern Zero Knowledge Cryptography课程笔记 Lecture 6: Algorithms for Efficient Cryptographic Operations (Jason Morton) Multi-scalar Multiplication(MSM) Naive: nP (((P P) P) P)… (2(2P))…Binary expand $n e_0e_1\alphae_2\alpha2\dots\e_{\…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
