我正在编写一个python3程序,它从命令行参数中获取要处理的文件的名称。关于处理不同编码的正确方法,我很困惑。
我认为我宁愿将文件名视为字节而不是字符串,因为这样可以避免使用错误编码的危险。实际上,我的一些文件名使用了不正确的编码(当我的系统区域设置使用utf-8时latin1),但这并不妨碍像ls这样的工具工作。我希望我的工具能够恢复它。
我有两个问题:命令行参数作为字符串给我(我使用argparse),我想将错误报告给用户作为字符串。
我已成功调整我的代码以使用二进制文件,并且我的工具可以处理当前默认编码中名称无效的文件,只要它是通过文件系统递归,因为我将参数转换为二进制文件,并在调用fs函数时使用二进制文件。但是,当我收到一个无效的文件名参数时,它会作为带有\udce8
等奇怪字符的unicode字符串传递给我。我不知道它们是什么,并且尝试编码它总是失败,无论是使用utf8还是使用相应的(错误的)编码(latin1)。
另一个问题是报告错误。我希望我的工具的用户解析我的stdout(因此想要保留文件名),但是当在stderr上报告错误时,我宁愿用utf-8编码它,用适当的“无效/问号”字符替换无效序列。
所以,
1)有更好的,完全不同的方式吗? (是的,修改文件名是有计划的,但我仍然希望我的工具能够健壮)
2)如何以原始二进制形式获取命令行参数(不为我预先解码),因为对于无效序列,重新编码已解码参数将失败,并且
3)如何告诉utf-8编解码器用无效的标记替换无效的,不可解码的序列而不是死在我身上?
答案 0 :(得分:2)
当我收到文件名参数时 然而,这是无效的 交给我作为unicode字符串 奇怪的人物,比如\ udce8。
这些是代理人物。低8位是原始的无效字节。
请参阅PEP 383: Non-decodable Bytes in System Character Interfaces。
答案 1 :(得分:-1)
不要反对谷物:文件名是字符串,而不是字节。
当您使用bytes
时,不应使用string
。 bytes
是一个整数元组。 string
是一个字符元组。它们是不同的概念。你正在做的就是在你应该使用布尔值时使用整数。
(除此之外:Python将所有字符串存储在Unicode下的内存中;所有字符串都以相同的方式存储。编码指定Python如何将文件上的字节转换为此内存格式。)
您的操作系统将文件名存储为特定编码下的字符串。我很惊讶你说有些文件名有不同的编码;据我所知,文件名编码是系统范围的。例如,open
等函数默认使用默认的系统文件名编码。