我越来越相信文件编码业务的目的是尽可能令人困惑。我在使用仅包含一行的utf-8
编码中读取文件时遇到问题:
“blabla this is some text”
(请注意,引号是标准引号的某些花哨版本。)
现在,我在其上运行这段Python
代码:
import fileinput
def charinput(paths):
with open(paths) as fi:
for line in fi:
for char in line:
yield char
i = charinput('path/to/file.txt')
for item in i:
print(item)
有两个结果: 如果我从命令提示符运行我的python代码,结果是一些奇怪的字符,然后是错误消息:
ď
»
ż
â
Traceback (most recent call last):
File "krneki.py", line 11, in <module>
print(item)
File "C:\Python34\lib\encodings\cp852.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position
0: character maps to <undefined>
我认为问题来自于Python试图错误地读取&#34;&#34;编码文档,但有没有办法订购fileinput.input
来阅读utf-8
?
notepad++
中保存与以前相同的文件之后,python代码现在在IDLE中运行并导致以下输出(删除换行符):
“blabla this is some text”
虽然如果我先输入chcp 65001
,我可以让命令提示不崩溃。运行该文件然后导致
Ä»żâ€śblabla this is some text ”
有什么想法吗?如果你问我,这是一个可怕的混乱,但我理解它是至关重要的......
答案 0 :(得分:9)
每个文件都经过编码。字节0x4C根据ASCII编码被解释为拉丁大写字母L,但是根据EBCDIC编码被解释为小于符号(&#39;&lt;&#;&#;&#;&#;&#;&#;&#; ...)。 没有像纯文本那样的事情。
像ASCII这样的单字节字符集使用单个字节来编码每个符号,有像KS X 1001这样的双字节字符集,它使用两个字节来编码每个符号,并且有像流行的UTF-8这样的编码每个符号使用可变数量的字节。
UTF-8已成为新应用程序最受欢迎的编码,因此我将举例说明:Latin Capital Letter A存储为单个字节:0x41
。 Left Double Quotation Mark(“)存储为三个字节:0xE2 0x80 0x9C
。表情符号Pile of Poo存储为四个字节:0xF0 0x9F 0x92 0xA9
。
任何读取文件并且必须将字节解释为符号的程序必须知道(或猜测)使用了哪种编码。
如果您不熟悉Unicode或UTF-8,可能需要阅读http://www.joelonsoftware.com/articles/unicode.html
Python 3的内置函数open()
有一个可选的关键字参数encoding
,以支持不同的编码。要打开UTF-8编码文件,您可以编写open(filename, encoding="utf-8")
,Python将负责解码。
此外,fileinput
模块通过openhook
关键字参数支持编码:fileinput.input(filename, openhook=fileinput.hook_encoded("utf-8"))
。
如果您不熟悉Python和Unicode或UTF-8,请阅读http://docs.python.org/3/howto/unicode.html 我还在http://www.chirayuk.com/snippets/python/unicode
中找到了一些不错的技巧在Python 2中open()
不知道编码。相反,您可以使用codecs
模块指定应使用的编码:codecs.open(filename, encoding="utf-8")
Python2 / Unicode启发的最佳来源是http://docs.python.org/2/howto/unicode.html