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

Python带附件邮件发送失败问题排查求助

问题分析与修复方案

主要问题分析

  1. 缺失必要的导入:代码中使用了MIMEApplication和basename,但未导入对应模块,执行时会抛出NameError,直接中断附件添加流程。
  2. 日志记录时机错误:logger.info(msg)在附件添加前执行,导致日志无法展示附件部分,无法排查问题。
  3. 文件路径误解:文件路径需为脚本运行目录的相对路径或绝对路径,与UTC路径、SMTP服务器路径无关。

修复后的完整代码

import smtplib
import logging
from pathlib import Path
from os.path import basename  # 新增导入:用于获取文件名
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication  # 新增导入:用于处理附件
from email.utils import COMMASPACE, formatdate

# 初始化日志(若项目已有日志配置可省略)
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)

def send_mail(send_to, subject, text, files=None, send_from='me@company.co.uk', 
        server='mail.company.co.uk', port=25):
    
    assert isinstance(send_to, list)

    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach(MIMEText(text))

    # 处理附件逻辑
    for f in files or []:
        try:
            # 验证文件是否存在
            file_path = Path(f)
            if not file_path.exists():
                logger.error(f"附件不存在:{file_path.resolve()}")
                continue
            
            with open(f, "rb") as fil:
                part = MIMEApplication(
                    fil.read(),
                    Name=basename(f)
                )
            # 设置附件头部信息
            part['Content-Disposition'] = f'attachment; filename="{basename(f)}"'
            msg.attach(part)
            logger.info(f"成功添加附件:{f}")
        except Exception as e:
            logger.error(f"添加附件失败:{str(e)}")

    # 附件处理完成后再记录完整邮件内容
    logger.info(msg.as_string())

    # 发送邮件
    smtp = smtplib.SMTP(server, port)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()

关键修复说明

  • 补充缺失导入:添加from os.path import basename和from email.mime.application import MIMEApplication,解决未定义变量错误。
  • 调整日志位置:将日志记录移至附件处理完成后,确保日志包含完整的邮件结构(含附件)。
  • 增加文件校验:新增文件存在性检查和异常捕获,避免单个附件问题导致整个邮件发送失败。
  • 路径明确说明:files参数支持两种路径形式:
    • 相对路径:相对于脚本运行时的当前工作目录(而非脚本文件所在目录)
    • 绝对路径:直接传入文件的完整路径(如/home/user/data/129279_20221030.csv)
      可通过print(Path(importfile).resolve())打印文件绝对路径,确认文件是否存在。

调用示例

保持原有调用方式即可,确保importfile指向正确路径:

send_mail(
    send_to=['recipient@somewhere.co.uk'], 
    subject='Something', 
    text='Something',
    files=[importfile]
)

内容的提问来源于stack exchange,提问作者somchai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:55:43