Skip to main content
 首页 » 编程设计

python之python写文件处理编码

2025年05月04日13lyj

我糊涂了。我需要帮助!!!
我正在处理一个包含汉字的文件,例如,我们称它为a.TEST,这就是里面的内容。

你好 中国 Hello China 1 2 3 


您不需要了解中文的意思。(实际上是“你好中国”)

>>> f=open('wr.TRAIN') 
>>> print f.read() 
你好 中国 Hello China 1 2 3 
 
>>> f.seek(0) 
>>> content = f.readline() 
>>> content 
'\xe4\xbd\xa0\xe5\xa5\xbd \xe4\xb8\xad\xe5\x9b\xbd Hello China 1 2 3\n' 
>>> print content 
你好 中国 Hello China 1 2 3 
>>> type(content) 
<type 'str'> 
>>> isinstance(content,unicode) 
False 


这是第一个问题:为什么当我只键入 utf-8时python shell给我 content的 content,同时 print content cmd可以输出我想要查看的形式?

第二个问题: unicode和 str有什么区别?
有人告诉我 encode将 unicode转换为 str,但是我从 Unicode HowTo中学到的内容告诉我 encode是 unicode转换 utf-8到 test.py

还没结束! :)

这是 .split()

#!/usr/bin/python 
#-*- coding: utf-8 -*- 
 
fr = open('a.TEST') 
fw = open('out.TEST','w') 
 
content = fr.readline() 
content_list = content.split() 
print content 
fw.write('{0}'.format(content_list)) 
 
fr.close() 
fw.close() 






第三个问题:为什么在我执行 fw.write('{0}'.format(content_list).decode('utf-8'))时汉字会变成utf-8代码?

我以为 out.TEST可以工作,但是不行。
我不希望 所写的是字符编码形式,我希望它完全是看起来像原来的字符(你好)。怎么做?

请您参考如下方法:

什么是编码

文件由字节组成。您可以用0到255之间的数字表示每个字节(或十六进制为0x00到0xFF)。

文本也写为字节。文本的书写方式已达成协议。那是一种编码。最基本的编码是ASCII,其他编码通常基于该编码。例如,ASCII定义数字65(0x41)代表'A',66(0x42)代表'B'等。

字符串如何表示

在python中,您可以使用数字值定义字符串:

>>> '\x41\x42\x43' 
'ABC' 


'\x41\x42\x43'与 'ABC'完全相同。 Python将始终使用更具可读性的文本表示形式( 'ABC')来表示字符串。

但是,某些数字值不是可打印的字符,因此它们将以数字形式表示:

>>> '\x00\x01\x02\x03\x04' 
'\x00\x01\x02\x03\x04' 


其他字符使用别名可以使您的工作更轻松:

>>> '\x0a\x0d\x09' 
'\n\r\t' 


不同的编码

ASCII table定义数字0-127的含义,并且仅包含英文字母。数字128-255未定义。因此,其他编码定义了128-255的含义。还有一些更改了整个范围0-255的含义。

有许多编码,它们对128-255的定义不同。

例如,字符185(0xB9)在Windows-1250编码中为 ą,但在iso-8859-2编码中为 š。

那么,如果打印 \xb9,会发生什么?这取决于控制台中使用的编码。就我而言(我的控制台使用cp852编码)是:

>>> print '\xb9' 
╣ 


由于存在这种歧义,因此字符串 '\xb9'永远不会表示为 '╣'(也不表示为 'ą' ...)。那将隐藏真实的价值。它将被表示为数值:

>>> '\xb9' 
'\xb9' 


也:

>>> '╣' 
'\xb9' 


另请参阅控制台中问题的字符串:

>>> content = '\xe4\xbd\xa0\xe5\xa5\xbd \xe4\xb8\xad\xe5\x9b\xbd Hello China 1 2 3\n' 
>>> 
>>> content 
'\xe4\xbd\xa0\xe5\xa5\xbd \xe4\xb8\xad\xe5\x9b\xbd Hello China 1 2 3\n' 
>>> 
>>> print content 
ńŻáňąŻ ńŞşňŤŻ Hello China 1 2 3 


但是,如果仅在控制台中输入变量,会发生什么?

在不带 print的cosole中输入变量时,将打印其表示形式。与以下内容相同:

>>> print repr(content) 
'\xe4\xbd\xa0\xe5\xa5\xbd \xe4\xb8\xad\xe5\x9b\xbd Hello China 1 2 3\n' 


什么是Unicode?

Unicode table旨在定义世界上所有字符的数字表示形式。它实际上可以做到这一点,因为它不限于256个值(或实际上没有任何其他限制)。这不是编码,而是数字到字符的通用映射。

例如,unicode定义数字353(0x0161)为字符 š。无论使用哪种语言环境和编码,这都是正确的。该字符可以任何支持 š的编码形式存储在文件(或内存)中。

什么是UTF-8?

在对Unicode字符进行编码时,可以使用任何编码,但是并非所有字符都支持所有字符。

例如, š(unicode 0x0161)可以在iso-8869-2中编码为0xB9,但根本不能在iso-8869-1中编码。

因此,为了能够对任何内容进行编码,您需要一种支持每个unicode字符的编码。 UTF-8是其中一种编码,但还有其他编码:

>>> u'\u0161'.encode('utf-7') 
'+AWE-' 
>>> u'\u0161'.encode('utf-8') 
'\xc5\xa1' 
>>> u'\u0161'.encode('utf-16le') 
'a\x01' 
>>> u'\u0161'.encode('utf-16be') 
'\x01a' 
>>> u'\u0161'.encode('utf-32le') 
'a\x01\x00\x00' 
>>> u'\u0161'.encode('utf-32be') 
'\x00\x00\x01a' 


utf-8的优点是整个ASCII范围保持不变,只要仅使用ASCII,每个字符仅使用一个字节:

>>> u'abcdefg'.encode('utf-8') 
'abcdefg' 


Python 2中的Unicode

重要说明:这确实是特定于Python 2的。Python3是不同的。

与 str对象是字节字符串不同, unicode对象是unicode字符字符串。

它们可以按选定的编码方式编码为 str,也可以按选定的编码方式从 str进行解码。

在开头的引号前使用 u指定unicode字符串。其中的字符使用当前编码解释,或者可以以数字格式 \uHEX指定:

>>> u'ABCD' 
u'ABCD' 
>>> 
>>> u'\u0041\u0042\u0043' 
u'ABC' 
>>> u'šâů' 
u'\u0161\xe2\u016f' 


现在的答案

第一个问题


contents打印 repr(contents)
print contents打印 contents


第二个问题

UTF-8字符串是字节字符串( str)。您可以通过对 unicode进行编码来获得它们:

>>> u'\u0161'.encode('utf-8') 
'\xc5\xa1' 
>>> '\xc5\xa1'.decode('utf-8') 
u'\u0161' 


因此,是的, encode将 unicode转换为 str。 str可以是utf-8,但不一定必须是。

第三题

A)“为什么在我执行.split()时汉字会变成utf-8代码?”

他们一直都是utf-8。

B)“我认为fw.write('{0}'。format(content_list).decode('utf-8'))可以工作”

content_list不是字符串。这是一个清单。当列表转换为字符串时,将使用其 repr(也对所有内容执行 repr)来完成。

例如:

>>> 'a \n a \n a' 
'a \n a \n a' 
>>> print 'a \n a \n a' 
a 
 a 
 a 
>>> print ['a \n a \n a'] 
['a \n a \n a'] 


最后打印的包含repr(str)的打印的repr(list)。