Python中文处理-乱码解决

概述

python中的字符串是一个字节的数组。 可以把他直接看成一个数组。
同样一个文本,不同格式下的字节数组是不同的。可以通过声明定义源文件(py文件)保存的格式。
通过decode和encode实现unicode和其他编码之间的转换。

从文件中读取的,或者 s=”你好” 得到的都是一个str类型的变量。
调用decode解码后得到的就是unicode类型的变量了。 它是两个字节算一个单位。
调用print 打印一个unicode会自动转换为操作系统的编码。

读写文件时,不能将unicode编码直接写文件,必须经过encode编码为str类型才可以。

演示


In [1]: # -*- coding:utf-8 -*-
In [2]: s = '你好'
In [3]: s
Out[3]: '\xe4\xbd\xa0\xe5\xa5\xbd'

In [4]: s.decode('utf-8')
Out[4]: u'\u4f60\u597d'

In [5]: b = s.decode('utf-8')
In [6]: b
Out[6]: u'\u4f60\u597d'

In [7]: print b
你好

In [8]: print s
浣犲ソ

In [9]: print s.decode('utf-8').encode('gbk')
你好

In [14]: b = u'你好'

In [15]: b
Out[15]: u'\u4f60\u597d'

In [16]: print b
你好

原则

  1. 使用-- coding:utf-8 -- 可以定义源文件的保存格式为utf-8 ,如果在文件中出现汉字,如s = ‘你好’,那么你好这个字是以utf-8方式存储的。如果定义为gbk编码,那么汉字就会以gbk方式存储。
  2. 如果你定义的编码方式和实际文件的保存格式不一致,那么就会乱码,所以声明的字符编码要和实际的字符编码一致。
  3. 使用decode(‘xxx’)函数可以将其他编码转换为统一的unicode编码。使用encode可以将unicode编码保存为其他编码。 编码和编码之间的转换可以以unicode作为中转
  4. print 函数应该是把字符认为就是unicode编码的,然后根据操作系统的编码方式,进行转码后输出。如果print 后跟的变量不是unicode编码,则会报错。
  5. 使用u’你好’的方式,可以直接声明一个unicode编码的字符串。文件保存是这个u’你好’中的你好,仍然是utf-8编码保存,但程序运行到这里, 会自动将它转码为unicode。见程序的In[15]和Out[15]

异常

当解码失败后,遇到不合适的字符,会出现异常。

UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe4 in position 0: ordinal not in range(128)

当一个文档中大部分字符是对的,就只有少数几个字符是错误的,可以通过加ignore参数来解决。如下

In [22]: s='中文'
In [23]: print type(s) #查看s的字符类型
<type 'str'>
In [24]: print s
涓枃
In [25]: s.decode('utf8') #解码utf8,默认的编码方式是unicode
Out[25]: u'\u4e2d\u6587'
In [26]: s.decode('gbk', "ignore") #解码utf8,忽略其中有异常的编码,仅显示有效的编码
Out[26]: u'\u6d93\u6783'
In [27]: s.decode('gbk', 'replace')
Out[27]: u'\u6d93\ufffd\u6783'
In [28]: print type(s)
<type 'str'>
In [29]: print s
涓枃
In [30]: s.encode('gb2312') #编码为utf8
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-30-83bfd0cc29ef> in <module>()
----> 1 s.encode('gb2312') ##编码为utf8

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

In [31]: print type(s)
<type 'str'>

写文件的例子

写文件有读写模式w和wb。 b代表二进制,如果你的字符是编码好的,那么就使用wb方式来写吧。这样内部不会做编码转换。 如果是用w模式,会做编码转换,如下:

#-*- encoding: utf-8 -*-
import locale
import sys, encodings, encodings.aliases

# 现在a是unicode的
a = u'喆'

f = open("aaa.txt", "w")
f.write(a)
f.close()

f.write会报错的。 使用

f.write(a.encode('utf-8'))

这样就没有错误了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值