Encoding issue when writing to text file, with Python
我正在编写一个程序,用一个简短的python脚本"手动"安排一个csv文件,使其成为正确的json语法。从输入文件中,我使用readlines()将文件格式化为一个行列表,然后将其操作并集中到一个字符串中,然后将该字符串输出到一个单独的.txt文件中。但是,输出包含输入文件中出现的乱码而不是希伯来文字符,并且输出是两倍行距的水平(在每个字符之间添加一个空格字符)。据我所知,问题与编码有关,但我还没弄清楚是什么。当我检测到输入和输出文件的编码(使用.encoding属性)时,它们都返回None,这意味着它们使用系统默认值。技术细节:python 2.7、windows 7。
虽然有很多关于这个话题的问题,但我没有找到我的问题的直接答案。在这种情况下,检测系统默认值对我没有帮助,因为我需要可移植的程序。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def txt_to_JSON(csv_list):
...some manipulation of the list...
return JSON_string
file_name ="input_file.txt"
my_file = open(file_name)
# make each line of input file a value in a list
lines = my_file.readlines()
# break up each line into a list such that each 'column' is a value in that list
for i in range(0,len(lines)):
lines[i] = lines[i].split("\t")
J_string = txt_to_JSON(lines)
json_file = open("output_file.txt","w+")
json_file.write(jstring)
json_file.close() |
- 值得注意的是,在使用python中的文件时,最好使用with语句。
- 你知道输入文件的编码是什么吗?
- @他在读希伯来文字符,但他在程序中使用的是ASCII码。这很可能是问题所在。
- 什么版本的python?
- 通常,python采用的是ascii,在处理用其他编码编码的文件时,必须指定输入编码和输出编码。(听起来有点滑稽:d)
- @保罗布:我不知道输入编码,正如我所说(也许我的编辑是在你的评论之后),我需要它是可移植的。
- 如果我使用的字符串是Unicode。也就是说,它已经被编码了,但我不知道编码是什么。如果是检测编码的问题,我理解这是一个棘手和不确定的业务,特别是因为这个程序可以在各种平台上使用,等等。
- 用notepad打开输入文件,选择另存为…,在编码所在的弹出窗口底部,选择utf-8,保存文件。现在您知道您的输入文件是utf8(它应该保持希伯来文字符的完整性),然后尝试使用该输入再次运行所有进程。如果它不起作用,请添加一个输入文件的简短示例,尝试在这里解析它,看看我是否可以。我还有windows/python2.7
- @保罗布,我希望这能在任何系统上运行。另外,我在这个程序上做测试的指导是使用一个保存为Unicode的文件,而不是UTF-8。
- @jeg622 unicode是一种超集编码。UTF-8是最标准化的编码的实现。python的unicode字符串在内部使用utf-8。这就是为什么我要用UTF-8保存文件的原因。为了在所有系统中都能工作,您必须至少在一个系统中工作。我们将在没有系统特定指令的情况下编写代码,但首先我们必须了解问题所在。
- @paulobu如果我将输入文件保存为utf-8,它会很好地工作!但是,有人指示我使用一个保存为Unicode的文件。我将询问我的团队领导关于这项指示的问题,并回复给你。
- 我很高兴。如果你想向你的领导解释一些背景知识,这些链接将非常有用,特别是第一个:joelonsoftware.com/articles/unicode.html、stackoverflow.com/questions/3951722/…和stackoverflow.com/questions/643694/utf-8-vs-unicode
所有数据都需要编码才能存储在磁盘上。如果你不知道编码,你能做的最好的就是猜测。这里有一个库:https://pypi.python.org/pypi/chardet
我强烈推荐内德·巴切尔德的演讲http://nedbatchelder.com/text/unipain.html详情。
有一个关于在Windows上使用"unicode"作为编码的解释:unicode和utf-8有什么区别?
TLDR:微软使用UTF16作为Unicode字符串的编码,但决定称之为"Unicode",因为他们也在内部使用它。
即使python2在字符串/unicode转换方面有点宽松,您也应该习惯于在输入时解码,在输出时编码。
以你为例
1 2 3 4 5 6 7 8 9 10 11 12
| filename = 'where your data lives'
with open(filename, 'rb') as f:
encoded_data = f.read()
decoded_data = encoded_data.decode("UTF16")
# do stuff, resulting in result (all on unicode strings)
result = text_to_json(decoded_data)
encoded_result = result.encode("UTF-16") #really, just using UTF8 for everything makes things a lot easier
outfile = 'where your data goes'
with open(outfile, 'wb') as f:
f.write(encoded_result) |
- 谢谢你的意见。但是,当我这样做时,输出文件(由f.write()创建)仍然被编码为ansi,所以当它到达希伯来文字符时,我会得到unicodeencodeerror。顺便说一句,utf_16是正确的符号。
- 在您的链接之后,我将编码从'utf_16'改为'utf_16_le',并得到了一个类似的错误,只与文件的开头有关,而不是与非ASCII字符有关。
- 你用什么程序打开输出文件?
- 我使用记事本。这将如何影响编码?
- 程序必须对文件进行解码以解释其中的内容。你能把这两个文件,或者类似的文件放在某个地方吗?我想看看
- 在一些额外的游戏之后(只是为了更好地了解正在发生的事情),我得出了额外的结论:1。将文件保存为"unicode",将codecs.open()与utf_16或utf_16_le一起用作编码,产生的结果类似于保存为"utf-8",并使用open()打开文件,唯一的区别是,当我将文件保存为"unicode"时,输出文件没有任何换行符2。使用codecs.open()与str.encode()有根本不同,但我不太明白为什么。
- 对于记录,这是输入文件。这个乱七八糟的文件可以在这里找到,尽管在我的电脑上,这个乱七八糟的文件看起来不一样,而且整个文件的间隔是两倍。正确的文件如下所示。出于某种原因,当我将文件上载到驱动器时,所有选项卡都消失了。
- 那么你有没有设法解决你的问题?
- codecs.open使用编码在读取时对文件中的数据进行解码,在写入时对其进行编码。所以在代码中,您只有Unicode字符串。它相当于f = open('filename', 'r+'); s = f.read().decode(encoding)和后来的f.write(s.encode(encoding)),所以u"asdf"。编码只是功能的一半。
- 是的,谢谢你的帮助,现在一切都很好!
您需要告诉python使用Unicode字符编码来解码希伯来语字符。下面是一个如何在python中读取unicode字符的链接:在python中从文件中读取字符
- 对不起,我没有找到解决办法。我尝试使用codecs模块,但输出没有任何变化。