命令行参数为字节而不是python3中的字符串

时间:2010-08-24 14:59:33

标签: encoding python-3.x filenames command-line-arguments

我正在编写一个python3程序,它从命令行参数中获取要处理的文件的名称。关于处理不同编码的正确方法,我很困惑。

我认为我宁愿将文件名视为字节而不是字符串,因为这样可以避免使用错误编码的危险。实际上,我的一些文件名使用了不正确的编码(当我的系统区域设置使用utf-8时latin1),但这并不妨碍像ls这样的工具工作。我希望我的工具能够恢复它。

我有两个问题:命令行参数作为字符串给我(我使用argparse),我想将错误报告给用户作为字符串。

我已成功调整我的代码以使用二进制文件,并且我的工具可以处理当前默认编码中名称无效的文件,只要它是通过文件系统递归,因为我将参数转换为二进制文件,并在调用fs函数时使用二进制文件。但是,当我收到一个无效的文件名参数时,它会作为带有\udce8等奇怪字符的unicode字符串传递给我。我不知道它们是什么,并且尝试编码它总是失败,无论是使用utf8还是使用相应的(错误的)编码(latin1)。

另一个问题是报告错误。我希望我的工具的用户解析我的stdout(因此想要保留文件名),但是当在stderr上报告错误时,我宁愿用utf-8编码它,用适当的“无效/问号”字符替换无效序列。

所以,

1)有更好的,完全不同的方式吗? (是的,修改文件名是有计划的,但我仍然希望我的工具能够健壮)

2)如何以原始二进制形式获取命令行参数(不为我预先解码),因为对于无效序列,重新编码已解码参数将失败,并且

3)如何告诉utf-8编解码器用无效的标记替换无效的,不可解码的序列而不是死在我身上?

2 个答案:

答案 0 :(得分:2)

  

当我收到文件名参数时   然而,这是无效的   交给我作为unicode字符串   奇怪的人物,比如\ udce8。

这些是代理人物。低8位是原始的无效字节。

请参阅PEP 383: Non-decodable Bytes in System Character Interfaces

答案 1 :(得分:-1)

不要反对谷物:文件名是字符串,而不是字节。

当您使用bytes时,不应使用stringbytes是一个整数元组。 string是一个字符元组。它们是不同的概念。你正在做的就是在你应该使用布尔值时使用整数。

(除此之外:Python将所有字符串存储在Unicode下的内存中;所有字符串都以相同的方式存储。编码指定Python如何将文件上的字节转换为此内存格式。)

您的操作系统将文件名存储为特定编码下的字符串。我很惊讶你说有些文件名有不同的编码;据我所知,文件名编码是系统范围的。例如,open等函数默认使用默认的系统文件名编码。