You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
)

几个关键修复点

  1. 变量作用域修正:把SMTP发送逻辑移到send_mail函数内部,确保msg变量能被正常访问。
  2. 语法错误修复:原来的导入语句import smtplib, os from ...不符合Python语法,拆分后才正确。
  3. 移除硬编码:把邮箱账号、服务器、文件名改成函数参数,让函数更通用,方便后续修改。
  4. 多附件支持:通过遍历files列表,实现一次性添加多个附件。
  5. 文件读取优化:用with open读取文件,避免手动关闭文件时可能出现的问题。

内容的提问来源于stack exchange,提问作者Tobias G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:17:48