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

Python EmailMessage发送邮件附件时内容为文件名而非写入内容问题

问题结论

不存在“同一段代码不能同时完成文件写入、附件添加发送”的限制,你拿到错误附件的核心原因是文件读写逻辑顺序写反了,和EmailMessage模块本身无关。

你的代码存在两个明确错误:

  • 用w+模式打开文件时,会立刻清空文件原有内容,初始文件指针停在文件开头。你刚打开就调用f.read(),此时文件已经被清空,只能读到空字符串。
  • 调用f.write('hey')写入内容后,文件指针会移动到写入内容的末尾,你没有将指针重置到文件开头,也没有重新读取写入后的内容,最终传给add_attachment的根本不是你写入的"hey"。
    你收到的附件显示为文件名,本质是传入的附件内容为空时,邮件客户端做的异常兼容显示。
两种可行实现方案

方案1:无需本地留存文件,直接构造附件

如果你只是想发送一个文件名为test.txt、内容为"hey"的附件,完全不需要在本地创建实体文件,直接把内容编码后传入即可:

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg['from'] = "blah_blah@gmail.com"
msg['To'] = "blah_blah@gmail.com"
msg['Subject'] = "This is TEST"

file_name = "test.txt"
content = "hey"
msg.add_attachment(
    content.encode('utf-8'),
    maintype='text',
    subtype='plain',
    filename=file_name
)

# SMTP连接推荐用with上下文管理,自动释放连接
with smtplib.SMTP(host='blah_blah_server.net', port=100) as s:
    s.send_message(msg)

方案2:需要本地留存test.txt,再读取文件发附件

如果你确实需要先把内容写入本地磁盘留存,再发送该文件,调整读写顺序即可,写完内容后要先把文件指针重置到开头再读取:

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg['from'] = "blah_blah@gmail.com"
msg['To'] = "blah_blah@gmail.com"
msg['Subject'] = "This is TEST"

file_name = "test.txt"
with open(file_name, 'w+') as f:
    f.write('hey')
    # 重置指针到文件开头,才能读取到刚写入的内容
    f.seek(0)
    file_data = f.read()

msg.add_attachment(
    file_data.encode('utf-8'),
    maintype='text',
    subtype='plain',
    filename=file_name
)

with smtplib.SMTP(host='blah_blah_server.net', port=100) as s:
    s.send_message(msg)
额外注意点
  • 所有IO操作(文件读写、SMTP连接等)都推荐用with上下文管理器,会自动处理连接关闭、缓冲区刷新,避免资源泄漏或者内容未写入磁盘的问题。
  • w+是覆盖写入模式,每次打开文件都会清空原有内容,如果需要在文件末尾追加内容,要改用a+模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.09 16:15:44