Python发送带附件邮件报错:NameError: name 'msg' is not defined
Python发送带附件邮件报错:NameError: name 'msg' is not defined 问题排查
嘿,我来帮你拆解这个问题——这个报错的原因其实挺直接的,咱们一步步理清楚:
核心问题所在
你定义的msg变量是**send_mail函数内部的局部变量**,但你执行smtp.sendmail和smtp.quit()的代码是放在函数外面的!函数内部的局部变量在外部完全不可见,Python自然找不到msg这个名字,于是抛出了NameError。
另外还有个小疏漏:你的send_mail函数本身没写完,发送邮件的核心逻辑(SMTP登录、发送、退出)应该放在函数内部,而不是单独拎出来执行。
修复后的完整代码
我帮你把代码修正并优化了,你可以直接参考下面的版本:
首先修正导入语句(原来的导入语法有错误):
import smtplib import os from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.utils import formatdate from email import encoders
然后是完善后的send_mail函数,以及调用示例:
# 替换成你存放附件的实际路径 attachment_path = "/your/actual/attachment/folder" os.chdir(attachment_path) def send_mail(send_from, send_to, subject, text, files, server, port, username='', password='', isTls=True): # 创建多部件邮件对象 msg = MIMEMultipart() msg['From'] = send_from msg['To'] = send_to msg['Date'] = formatdate(localtime=True) # 把原来硬编码的主题改成传入参数,更灵活 msg['Subject'] = subject # 添加邮件正文 msg.attach(MIMEText(text)) # 处理附件:支持同时添加多个附件 for file in files: part = MIMEBase('application', "octet-stream") # 用with语句读取文件,自动关闭句柄更安全 with open(file, "rb") as f: part.set_payload(f.read()) encoders.encode_base64(part) part.add_header('Content-Disposition', f'attachment; filename="{os.path.basename(file)}"') msg.attach(part) # 把SMTP发送逻辑移到函数内部,这样就能正常访问msg变量了 try: smtp = smtplib.SMTP(server, port) if isTls: smtp.starttls() smtp.login(username, password) smtp.sendmail(send_from, send_to, msg.as_string()) finally: # 无论发送成功与否,都确保关闭SMTP连接 smtp.quit() # 调用函数发送邮件,替换成你的实际信息 send_mail( send_from='test@test.de', send_to='xyz', subject='测试带附件邮件', text='这是邮件的正文内容', files=['Olaf.xlsx'], # 可以添加多个附件,比如['Olaf.xlsx', 'report.pdf'] server='smtp.web.de', port=587, username='test@test.de', password='你的邮箱密码', isTls=True )
几个关键修复点
- 变量作用域修正:把SMTP发送逻辑移到
send_mail函数内部,确保msg变量能被正常访问。 - 语法错误修复:原来的导入语句
import smtplib, os from ...不符合Python语法,拆分后才正确。 - 移除硬编码:把邮箱账号、服务器、文件名改成函数参数,让函数更通用,方便后续修改。
- 多附件支持:通过遍历
files列表,实现一次性添加多个附件。 - 文件读取优化:用
with open读取文件,避免手动关闭文件时可能出现的问题。
内容的提问来源于stack exchange,提问作者Tobias G.
相关产品推荐
相关产品推荐

