当前位置:首页 > 文章列表 > 文章 > python教程 > Python mailbox.get_bytes 怎样控制是否保留信封头

Python mailbox.get_bytes 怎样控制是否保留信封头

来源:17golang原创 2026-11-10 07:50:39 0浏览 收藏

如果你用 Python 读取 mbox 邮件,关键不是改写返回结果,而是在调用 mbox.get_bytes() 时选择 from_ 参数:from_=False(默认值)会去掉每条记录最前面的 Unix From 信封行,from_=True 则把它保留下来。邮件头里的 From: 与这条信封行不是同一个字段。

官方地址:https://docs.python.org/3/library/mailbox.html

本文用一个最小 mbox 项目生成测试邮件、读取同一个 key,并打印两种字节结果。需要保留原始 mbox 记录边界时选 True;只想交给 email 解析器处理标准邮件头和正文时,通常选默认的 False。

先分清 mbox 信封行和邮件头

mbox 文件中的一条记录通常以 Unix “From ” 行开始,例如 From alice@example.com Tue Nov 10 10:00:00 2026。它是 mbox 存储格式用来分隔记录的信封信息,不是 RFC 5322 邮件头;真正的邮件头从 Subject:、Date:、From: 这类字段开始。

mailbox.Mailbox.get_bytes(key) 返回邮件的字节表示。对 mailbox.mbox 来说,方法多了一个 from_ 参数:默认不返回首行,传入 True 才保留首行。这个差异适合用字节首行直接观察,而不要用邮件头字典去判断。

mbox 文件经 get_bytes from_ 参数分成两种字节结果的结构图
图1:mbox 信封行、邮件头和正文的读取关系,这是静态结构说明图,不是运行截图。

准备一个可重复运行的小项目

先创建一个临时目录,再用 mailbox.mbox 写入一封测试邮件。示例显式调用 lock()、flush() 和 close(),这样不会把“正在写入”和“正在读取”的状态混在一起。

from email.message import EmailMessage
from pathlib import Path
import mailbox

# 使用项目目录中的 mbox 文件,重复运行前先清理旧测试数据。
mbox_path = Path("demo-mailbox.mbox")
if mbox_path.exists():
    mbox_path.unlink()

# 组装一封最小邮件,便于后面比较返回字节的首行。
message = EmailMessage()
message["From"] = "alice@example.com"
message["To"] = "bob@example.com"
message["Subject"] = "mailbox get_bytes demo"
message.set_content("保留或去掉 mbox 信封行都不应改变正文。")

# 写入 mbox 后刷新并关闭,确保读取阶段看到完整记录。
box = mailbox.mbox(mbox_path, create=True)
box.lock()
try:
    box.add(message)
    box.flush()
finally:
    box.close()

print(f"测试文件:{mbox_path}")

这段代码只负责准备输入。mbox.add() 返回的 key 会在读取阶段重新从 mailbox 中取得,不要假设 key 永远是字符串或从零开始的整数。

用 from_=False 去掉信封行

读取时先使用默认值。这里把返回结果按行拆开,只展示前几行并标出首行;由于 from_=False,第一行应该已经是邮件头,而不是以大写 From 开头的 mbox 分隔行。

import mailbox
from pathlib import Path

# 以只读方式打开准备好的 mbox,key 从实际内容中取得。
box = mailbox.mbox(Path("demo-mailbox.mbox"), create=False)
try:
    key = next(iter(box))

    # 默认 from_=False:去掉 mbox 记录顶部的 Unix From 信封行。
    raw_without_envelope = box.get_bytes(key, from_=False)
    first_line = raw_without_envelope.splitlines()[0].decode("ascii", "replace")
    print(f"首行:{first_line}")
finally:
    # 读取完成后关闭文件句柄;不需要写锁时不要额外修改 mailbox。
    box.close()
首行:From: alice@example.com

这里打印的 From: 是邮件头,保留它是解析发件人信息所需要的;被去掉的是 mbox 存储层的 From 信封行。若你的下游代码使用 email.parser.BytesParser,通常把默认结果交给解析器就够了。

用 from_=True 保留原始信封行

当目标是导出 mbox 原始记录、保留记录边界,或者把字节交给仍然期待 Unix From 行的下游工具时,传入 from_=True。下面把两种结果的首行放在一起比较。

import mailbox
from pathlib import Path

# 同一个 key 读取两次,只改变 from_,方便比较存储层首行。
box = mailbox.mbox(Path("demo-mailbox.mbox"), create=False)
try:
    key = next(iter(box))
    raw_without_envelope = box.get_bytes(key, from_=False)
    raw_with_envelope = box.get_bytes(key, from_=True)

    # 用 replace 处理不可见的回车换行,输出只承担验收作用。
    line_without = raw_without_envelope.splitlines()[0].decode("ascii", "replace")
    line_with = raw_with_envelope.splitlines()[0].decode("ascii", "replace")
    print("from_=False:", line_without)
    print("from_=True :", line_with)
finally:
    # get_bytes 不会替代 mailbox 的生命周期管理,读取结束仍要关闭对象。
    box.close()
from_=False: From: alice@example.com
from_=True : From alice@example.com Tue Nov 10 10:00:00 2026

两份结果的邮件头和正文内容相同,区别集中在最前面的信封行。实际时间字符串由 mbox 写入过程决定,示例输出只用于说明形状,不应把时间当成业务字段。

from_ false 与 true 返回字节首行差异的对比说明图
图2:两种参数只在 mbox 顶部信封行的保留与否上产生差异,这是静态结果说明图,不是运行截图。

按场景选择参数,不要混淆邮件格式

场景建议调用原因
解析邮件头和正文get_bytes(key)默认去掉存储层信封行,输入更接近标准邮件内容。
导出一条完整 mbox 记录get_bytes(key, from_=True)保留记录分隔所需的 Unix “From ” 首行。
使用 Maildir、MH 等 mailboxget_bytes(key)不要把 mbox 的额外参数直接套到所有 Mailbox 子类。

官方文档把 from_ 标为 mbox.get_bytes() 的额外参数;mailbox.MMDF 也提供同类控制。其他 mailbox 类型的 get_bytes() 签名并不保证接受这个参数,所以跨格式代码应把是否保留信封行作为 mbox/MMDF 分支处理。

运行验收和常见问题

把前面的代码保存为 mailbox_get_bytes_demo.py 后,在空目录运行:

# 运行最小项目,先生成 mbox,再比较两种 from_ 结果。
python3 mailbox_get_bytes_demo.py

验收只看两个事实:from_=False 的首行应是 From: 等邮件头,from_=True 的首行应是以 From 开头的信封行。如果调用的 key 不存在,官方 API 会抛出 KeyError,这说明读取对象和 key 生命周期需要重新对应,不是 from_ 参数失效。

为什么看到两个 From?

From: 是邮件头字段,From (没有冒号)是 mbox 记录的 Unix 信封行。它们可以同时存在,不能只按单词相同就认为是重复字段。

能不能把 from_ 传给 mailbox.Maildir?

不要这样写。from_ 是 mbox/MMDF 针对存储格式提供的额外参数;对 Maildir 使用通用的 get_bytes(key),需要原始格式时再按对应 mailbox 类型的文档设计处理。

读取后还要 flush 吗?

纯读取不需要为了 get_bytes() 额外调用 flush(),但打开对象应在结束时 close()。只有在你对 mailbox 做了新增、删除或修改并希望落盘时,才按写入流程加锁、刷新和关闭。

小结

Python mailbox.get_bytes() 控制信封头的答案就是 mbox 的 from_ 参数:默认 False 去掉 Unix “From ” 行,True 保留它。把这个选择放在“标准邮件解析”与“原始 mbox 记录导出”的边界上,就能避免把存储格式信息误当成邮件头,也能让跨 mailbox 类型的代码更稳妥。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Hyperlight 展示 Linux 微虚拟机运行方式,隔离边界在哪里Hyperlight 展示 Linux 微虚拟机运行方式,隔离边界在哪里
上一篇
Hyperlight 展示 Linux 微虚拟机运行方式,隔离边界在哪里
Range.extractContents 怎样移动选中的部分 DOM 内容
下一篇
Range.extractContents 怎样移动选中的部分 DOM 内容
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    966次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    967次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1077次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1058次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    889次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码