您的当前位置:首页正文

基于Python的数据分析(2):字符串编码

2021-08-19 来源:星星旅游
基于Python的数据分析(2):字符串编码

在上⼀篇⽂章《》中的第四个步骤中我们在python的启动步骤中强制要求加载sitecustomize.py⽂件并设置其默认编码为“utf-8”。本篇⽂章会介绍为什么要增加这个⽂件以及如何处理python的字符串编码的问题。

字符串变量和unicode值

字符串变量是所有编程语⾔⾥⾯定义多字符的⼀种变量类型。

在python中我们必须区分清楚字符串变量和unicode值这两个的区别。在其他的语⾔或者在python3.0以上的版本中,定义字符串的时候就是定义的该字符串的unicode的值(有特别设定的除外)。但是在python2.7(或者低于2.7的版本)中,字符串str的定义的是8位⽂本和⼆进制数据,这意味着什么呢,如果你编码定义字符串的平台默认是以GBK编码的话,那么所定义的字符串也就是GBK编码,我们可以验证⼀下是否如此:在下图中,在python shell⾥⾯定义⼀个字符创”abc中⽂“,我们发现,只有⽤gbk编码去解码decode才能正常识别该字符串,那么我们就可以说我使⽤的这个python shell默认的是gbk编码字符,因为字符串变量s是被gbk编码了。

⼤家可以会说,⽤gbk编码也没什么问题啊,反正可以正常读写。事实上,这样理解是⽚⾯的,在涉及到python处理⽂本、数据库、⽹络流的数据的过程中时候,有其他平台的字符串要交互的时候就会报错,例如我输出gbk编码的字符串到以utf8编码存储的数据库的时候,在数据库中该字符串是以乱码存在的,这个逻辑类似于于⼀个法国⼈跟我⼀个只会讲中⽂和英⽂的中国⼈来说法⽂的时候,我接受到的都是⽆效信息(事实上我根本不知道他在说什么)。

这时候就需要⼀个转义的机制存在,同样以上⾯这个法国⼈和中国⼈聊天的例⼦为例,如果他们都是以各⾃国家的⽅⾔进⾏聊天的话,肯定是鸡同鸭讲,但是如果以英语作为公共语⾔交流就不会出现问题。在python2.7中我们同样需要做⼀下这个操作,就是把所有的编码都转成⼀个统⼀的编码,⼀个普遍的解决⽅案就是采⽤字符串的

unicode。字符的unicode是业界的⼀种标准,它可以使电脑得以呈现世界上数⼗种⽂字的系统。 在计算机技术全球化发展的阶段,程序猿们纷纷觉得太多编码导致世界变得过于复杂了,让⼈脑袋疼,于是⼤家坐在⼀起拍脑袋想出来⼀个⽅法:所有语⾔的字符都⽤同⼀种字符集来表⽰,这就是Unicode。

转义的操作分两个encode和decode两个操作。decode就是把编码字符按照其设定的编码格式解码成unicode,encode就是把unicode按照特定的编码格式编码成某种编码字符,例如:在下图操作中,我们把s.decode(“gbk”)后获得s的unicode值存储在s中,并对s进⾏两种编码分别得到s1和s2。为了加深⼤家的理解,我画了下图:

字符串在Python内部的表⽰是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另⼀种编码decode的作⽤是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表⽰将gb2312编码的字符串str1转换成unicode编码。encode的作⽤是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表⽰将unicode编码的字符串str2转换成gb2312编码。因此,转码的时候⼀定要先搞明⽩,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码。代码中字符串的默认编码与代码⽂件本⾝的编码⼀致

如何解决编码问题

好的。现在我们在python2.7中怎样解决编码问题了:

1.加⼊sitecustomize.py,告诉python你启动以后就⽤utf-8编码来解决编码的问题。就是告诉python默认奖unicode值编码成为utf-8,除⾮我明确设定了。

sitecustomize.py is a special script; Python will try to import it on startup, so any code in it will be run automatically. As the comment mentions, it can go anywhere (aslong as import can find it), but it usually goes in the site-packages directory within your Python lib directory.

setdefaultencoding function sets, well, the default encoding. This is the encoding scheme that Python will try to use whenever it needs to auto-coerce a unicode stringinto a regular string.

⼤家可以⾃⼰做⼀下测试,import sys这个包,然后打印sys.path,会有下⾯的输出:

['D:\\\\Workspace\\\\Code\\\\hekejun', 'D:\\\\Workspace\\\\Code', 'C:\\\\Windows\\\\system32\\\\python27.zip', 'C:\\\\Python27\\\\DLLs', 'C:\\\\Python27\\\\lib', 'C:\\\\Python27\\\\lib\\\\plat-win','C:\\\\Python27\\\\lib\\\\lib-tk', 'C:\\\\Python27', 'C:\\\\Python27\\\\lib\\\\site-packages', 'C:\\\\Python27\\\\lib\\\\site-packages\\\\win32', 'C:\\\\Python27\\\\lib\\\\site-packages\\\\win32\\\\lib','C:\\\\Python27\\\\lib\\\\site-packages\\\\Pythonwin', 'C:\\\\Python27\\\\lib\\\\site-packages\\\\wx-3.0-msw']

前⾯两个路径是我运⾏的代码所在的⽬录,往下看,我们可以看到'C:\\\\Python27\\\\lib\\\\site-packages'这个⽬录,在这个⽬录下,python会⾃动加载sitecustomize.py。2.将⽂件格式设定为utf-8编码。就是在每个.py⽂件(python源⽂件)的⾸⾏加⼊这⼀⾏声明:

#-*- coding: utf-8 -*-

事实上python只认#、coding和编码字符创,其他的只为了好看,是的你没看错,只为了好看⽽已。

3.定义任⼀字符串变量s的时候,如果该字符串包括⾮字幕数字以外的字符,尤其是含有中⽂字符的时候,⽤下⾯任⼀声明⽅式:

s=u\"abc中⽂\"

s=\"abc中⽂\".decode(\"utf-8\")

4.在实际处理字符的过程中如果遇到不知道什么编码的,建议下载⼀个第三⽅包chardet,然后⽤下⾯的⽅法去分析即可

import chardets1=\"中⽂abc\"

print chardet.detect(s1)s2=u\"中⽂abc\".encode(\"GBK\")print chardet.detect(s2)

注意第⼆段代码,chardet分析GBK编码或者GB2312编码的字符的时候总是分析为“KOI8-R”编码,原因⽹上搜索了也不知道为啥,估计是内部的⼀个不够。其他编码可以正常分析得到。

注意chardet不能去分析unicode,不然会报错,当然这也可以作为探测的⼀种⼿段吧,如果报错那么说明当前的字符串是unicode呗。

import chardets3=u\"abc中⽂\"

print chardet.detect(s3)

Traceback (most recent call last):

File \"D:\\Test.py\", line 81, in print chardet.detect(s3)

File \"C:\\Python27\\lib\\site-packages\\chardet\\__init__.py\", line 25, in detect raise ValueError('Expected a bytes object, not a unicode object')ValueError: Expected a bytes object, not a unicode object

因篇幅问题不能全部显示,请点此查看更多更全内容