我有一个简单的Python(2.7.10)程序,如下所示:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
with open("test.txt") as f:
input = f.readlines()
for i in input:
l = list(i)
mystring = ""
for j in l:
mystring += j
print mystring, '\n',
文本文件'test.txt'包含:
AAAÖÖAAA
但是当我运行代码时,每次'Ö'都在mystring的末尾时,它会输出为'?',如下所示:
A
AA
AAA
AAA?
AAAÖ
AAAÖ?
AAAÖÖ
AAAÖÖA
AAAÖÖAA
AAAÖÖAAA
AAAÖÖAAA
如果我在Python 3上运行代码(必须将print语句更改为
'print (mystring),
'),输出正确:
A
AA
AAA
AAAÖ
AAAÖÖ
AAAÖÖA
AAAÖÖAA
AAAÖÖAAA
AAAÖÖAAA
有人知道为什么会这样,以及如何解决这个问题?我试过谷歌搜索但没有找到任何东西。
答案 0 :(得分:3)
您正在打印UTF-8 bytes。
UTF-8是一种可变字节编码;它将使用1到4个字节之间的任何位置来编码给定的Unicode代码点。 Ö
在UTF-8中被编码为两个字节,而字母A
只需要一个:
>>> u'Ö'.encode('utf8')
'\xc3\x96'
>>> u'A'.encode('utf8')
'A'
仅打印第一个字节(十六进制C3)无效UTF-8输出,因此终端使用?
表示无法解码您打印的数据。在我的Mac终端上,在这种情况下打印U+FFFD REPLACEMENT CHARACTER �
字符:
>>> print u'Ö'.encode('utf8')
Ö
>>> print u'Ö'.encode('utf8')[0]
�
>>> print u'Ö'.encode('utf8')[1]
�
如果您首先将数据解码为unicode
对象,则可以迭代代码点而不是字节:
for i in input:
l = list(i.decode('utf8'))
请注意,您不必在对象上调用list()
进行迭代。循环一个字符串已经为你提供了单独的字符。
您也可以使用io.open()
打开文件;这为您提供了一个文件对象,在阅读时默认为您提供unicode
个对象,前提是您告诉它使用哪个编解码器:
import io
with io.open("test.txt", encoding='utf8') as f:
input = f.readlines()
答案 1 :(得分:3)
解决Python 2问题的另一种方法。
而不是使用open()
...
with open("test.txt") as f:
input = f.readlines()
...使用io.open()
:
import io
with codecs.open('/tmp/b') as f:
input = f.readlines()
io.open()
与Python 3 open()
内置的行为相同。