带有python和fileinput的Unicode文件

时间:2014-07-15 09:43:24

标签: python utf-8

我越来越相信文件编码业务的目的是尽可能令人困惑。我在使用仅包含一行的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 ”

有什么想法吗?如果你问我,这是一个可怕的混乱,但我理解它是至关重要的......

1 个答案:

答案 0 :(得分:9)

编码

每个文件都经过编码。字节0x4C根据ASCII编码被解释为拉丁大写字母L,但是根据EBCDIC编码被解释为小于符号(&#39;&lt;&#;&#;&#;&#;&#;&#;&#; ...)。 没有像纯文本那样的事情。

像ASCII这样的单字节字符集使用单个字节来编码每个符号,有像KS X 1001这样的双字节字符集,它使用两个字节来编码每个符号,并且有像流行的UTF-8这样的编码每个符号使用可变数量的字节。

UTF-8已成为新应用程序最受欢迎的编码,因此我将举例说明:Latin Capital Letter A存储为单个字节:0x41Left 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中读取文件

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中的字符串

在Python 2中open()不知道编码。相反,您可以使用codecs模块指定应使用的编码:codecs.open(filename, encoding="utf-8")

Python2 / Unicode启发的最佳来源是http://docs.python.org/2/howto/unicode.html