【问题标题】:Unicode file with python and fileinput带有 python 和 fileinput 的 Unicode 文件
【发布时间】:2014-07-15 09:43:23
【问题描述】:

我越来越相信,文件编码业务是故意使之尽可能混乱。我在读取仅包含一行的 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 尝试读取“错误”编码的文档这一事实,但有没有办法命令 fileinput.input 读取 utf-8


编辑:发生了一些非常奇怪的事情,我知道它是如何工作的。在notepad++ 中保存与之前相同的文件后,python 代码现在在 IDLE 中运行并产生以下输出(已删除换行符):

“blabla this is some text”

如果我先输入chcp 65001,我可以让命令提示符不崩溃。运行文件然后结果

Ä»żâ€śblabla this is some text ”

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

【问题讨论】:

  • 尝试更改代码页设置?
  • @PadraicCunningham 你这是什么意思?
  • 您是从 Windows shell 运行它的吗?
  • @PadraicCunningham 在 Windows 7 命令提示符下,是的。
  • 不是完全重复,但答案stackoverflow.com/a/11544596/3218018 会有所帮助

标签: python utf-8


【解决方案1】:

编码

每个文件都经过编码。字节 0x4C 根据 ASCII 编码被解释为拉丁大写字母 L,但根据 EBCDIC 编码被解释为小于号 ('没有纯文本这样的东西。

有像 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

【讨论】:

  • 关于 fileinput.input() 您不能根据 python 3 文档将 openhook 和 inplace 结合起来。如果我需要两者,因为我想逐行更改其编码未被猜测/设置的文件。
  • @Timo 我出于同样的原因来到这里,到目前为止我只找到了this 的答案,建议自己做
  • @lucidbrot this 是我做的,所以使用open 两次,用于阅读和写作。
猜你喜欢
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 2010-09-28
  • 1970-01-01
  • 1970-01-01
  • 2017-09-10
相关资源
最近更新 更多