为了解决这个问题,我试图围绕 Python 标准库中旨在支持RFC 2231的各种函数。该 RFC 的主要目的似乎有三个方面:允许在标头参数中使用非 ASCII 编码,注意给定值的语言,以及允许标头参数跨越多行。该email.util
库提供了几个函数来处理这方面的各个方面。据我所知,它们的工作方式如下:
decode_rfc2231
仅将此类参数的值拆分为其部分,如下所示:
>>> email.utils.decode_rfc2231("utf-8''T%C3%A4st.txt")
['utf-8', '', 'T%C3%A4st.txt']
decode_params
负责检测 RFC2231 编码的参数。它收集属于一起的部分,并将 url 编码的字符串解码为字节序列。然而,这个字节序列随后被编码为 latin1。并且所有值都用引号引起来。此外,对第一个参数有一些特殊处理,它仍然必须是两个元素的元组,但是这两个元素无需修改就被传递给结果。
>>> email.utils.decode_params([
... (1,2),
... ("foo","bar"),
... ("name*","utf-8''T%C3%A4st.txt"),
... ("baz*0","two"),("baz*1","-part")])
[(1, 2), ('foo', '"bar"'), ('baz', '"two-part"'), ('name', ('utf-8', '', '"Täst.txt"'))]
collapse_rfc2231_value
可用于将这三元组的编码、语言和字节序列转换为适当的 unicode 字符串。然而,让我感到困惑的是,如果输入是这样一个三元组,那么引号将被转移到输出中。另一方面,如果输入是单引号字符串,则这些引号将被删除。
>>> [(k, email.utils.collapse_rfc2231_value(v)) for k, v in
... email.utils.decode_params([
... (1,2),
... ("foo","bar"),
... ("name*","utf-8''T%C3%A4st.txt"),
... ("baz*0","two"),("baz*1","-part")])[1:]]
[('foo', 'bar'), ('baz', 'two-part'), ('name', '"Täst.txt"')]
所以似乎为了使用所有这些机制,我必须再添加一个步骤来取消引用我遇到的任何元组的第三个元素。这是真的,还是我在这里遗漏了一些观点?我不得不在源代码的帮助下弄清楚上述很多内容,因为文档对细节有点模糊。我无法想象这种选择性取消引用背后的意义是什么。有什么意义吗?
关于如何使用这些功能的最佳参考是什么?
到目前为止,我发现的最好的是实施。在那里,该过程似乎与上面概述的大致相同,但是每个字段都通过, 之后没有引用,并且仅折叠它们的值,所有其他字段都返回一个元组。我希望有更有用的东西。email.message.Message
_unquotevalue
decode_params
get_filename
get_boundary