Python的open("x", "r")函数,我如何知道或控制文件应该具有哪种编码?

8
如果一个Python脚本使用open("filename", "r")函数打开并读取文本文件的内容,我该如何确定这个文件应该具有哪种编码?
请注意,由于我正在从自己的程序中执行此脚本,如果通过环境变量可以控制此操作的任何方式,那么对我来说就足够了。
顺便说一下,这是Python 2.7。
相关代码来自Mercurial,它可以通过磁盘上的文件而不是通过命令行将文件添加到存储库中。因此,基本上不是这样:
hg add A B C

我可以将A、B和C写入文件中,每个之间用换行符分隔,然后执行以下操作:

hg add listfile:input.txt

读取此文件的代码如下所示:
files = open(name, 'r').read().split(delimiter)

因此,我有一个问题。当我询问应该使用哪种编码时,在IRC上给我的答案是这样的:

当你在命令行中传递文件参数时使用的编码与它相同

我理解为当我执行Mercurial(hg)时使用的编码与此相同。因为我不知道那是哪种编码,所以我把所有东西都交给.NET进程对象,现在在这里问问。
1个回答

6
你无法做到。读取文件与其编码无关;你需要事先知道编码以便正确解释所读取的字节。例如,如果你知道文件是使用UTF-8编码的:
with open('filename', 'rb') as f:
    contents = f.read().decode('utf-8-sig')    # -sig deals with BOM, if present

或者,如果您知道该文件仅为 ASCII:

with open('filename', 'r') as f:
    contents = f.read()    # results in a str object

如果您真的不知道文件的编码方式,那么就无法保证您能正确地阅读它;但是,您可以使用像chardet这样的工具猜测编码方式。
更新:
我现在明白了你的问题。我以为你有一个需要编写代码的文件,但似乎你需要为文件编写代码 ;-)
所涉及的代码可能只处理纯ASCII(字符串可能稍后转换,但我认为这不太可能)。因此,您需要创建一个仅包含ASCII字符(代码点<128)的文本文件,并确保它以ASCII编码保存(即不是UTF-16或类似的编码方式)。考虑到Mercurial处理文件名,其中可能包含Unicode字符,这有点不幸。

1
所以基本上编码是ASCII,你是这个意思吗?相关的代码看起来像这样:files = open(name, 'r').read().split(delimiter) - Lasse V. Karlsen
@Lasse:不完全正确。我的意思是,只有在你知道编码是ASCII时才应该这样做(否则你会得到一个字节序列而不是字符)。请查看Python Unicode文档以获取更多信息。 - Cameron
我不完全确定我理解你的评论。有问题的代码不能由我更改。换句话说,无论好坏,我都必须符合代码期望的任何编码(或缺乏编码)。从你的回答中看来,编码只是ASCII。如果是这样,那就是这样了。 - Lasse V. Karlsen
事实证明,Mercurial似乎根本无法处理文件名中的Unicode字符。即使我要求Mercurial自己发现一个带有合法字符的文件,这个字符通常不会出现在源代码文件名中,但当它找不到该文件时,它仍然会崩溃。显然,它将字符解释为其他内容,然后无法定位该文件。 - Lasse V. Karlsen
结果发现,如果我使用Windows-1252,那些在该代码页中可表示的文件名会被正确地读入Mercurial,就目前而言看起来如此,所以我暂时会坚持使用它。 - Lasse V. Karlsen
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接