解决Python2.x编码之殇-转载,做个备份
发布时间:2022-09-26 14:38:01 所属栏目:Linux 来源:
导读: 解决Python2.x编码之殇
Python编码问题一直困扰了我许久,之前有过一些总结,但并不系统,比较凌乱。当然python2.x编码问题本身,便是剪不断理还乱。本篇将系统介绍python2.x编程中会遇到的一些编码问题
Python编码问题一直困扰了我许久,之前有过一些总结,但并不系统,比较凌乱。当然python2.x编码问题本身,便是剪不断理还乱。本篇将系统介绍python2.x编程中会遇到的一些编码问题
|
解决Python2.x编码之殇 Python编码问题一直困扰了我许久,之前有过一些总结,但并不系统,比较凌乱。当然python2.x编码问题本身,便是剪不断理还乱。本篇将系统介绍python2.x编程中会遇到的一些编码问题,并给出解决方案。基于对编码问题的摸索了解,我也尝试写了一个编码转换模块 Transcode ,应该能解决绝大部分新手的疑难杂症。当然,python大神可以绕道而行,至于使用3.x的朋友,以后将会成文介绍。 python编程中会经常遇到操作系统编码、文件编码、控制台输入输出编码、网页编码、源代码编码、python编码,本文将会逐一介绍。首先我们来看看一些常见的编码情况: print sys.getdefaultencoding() #系统默认编码 print sys.getfilesystemencoding() #文件系统编码 print locale.getdefaultlocale() #系统当前编码 print sys.stdin.encoding #终端输入编码 print sys.stdout.encoding #终端输出编码 将以上这段代码在windows与linux系统下分别运行,查看输出结果。 windows终端结果: ascii mbcs ('zh_CN', 'cp936') cp936 cp936 Linux终端结果: ascii UTF-8 ('zh_CN', 'UTF-8') UTF-8 UTF-8 操作系统编码 操作系统默认编码可以通过sys.getdefaultencoding()函数获取,可以看到windows与linux下默认都为ascii编码,而我们知道ascii编码不支持中文。那么操作系统编码将在python程序的何处会被用到呢?何时又会引发血案? 触发异常点 经过测试,我发现当需要将unicode格式的字符串存入到文件时,python内部会默认将其先转换为Str格式的系统编码,然后再执行存入步骤。而在这过程中,容易引发ascii异常。 实例证明: #! -*- coding:utf-8 -*- a=u"中文" f=open("test.txt","w") f.write(a) 报错异常信息:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-1…… 说明:因为ascii不支持中文,而变量a为unicode格式的中文字符串,因此无法进行编码而引发异常。 解决方案 设置系统编码为utf-8或者gbk。 import sys reload(sys) sys.setdefaultencoding('gbk') 说明:在windows下将其设置为gbk,在linux在设置为utf-8. 终端编码 windows下终端指的是控制台,在控制台上输入输出有着其本身的编码格式,如windows控制台输入输出编码都为cp936。原谅我是第一次看到此编码,于是上网查了会,发现其实它就是常见的GBK编码;而linux终端的输入输出编码都为utf-8。如果我们编写的程序,不会再终端输入输出任何内容,则可以忽略此编码,如若不然终端编码将会非常重要。 乱码点 我们在终端执行python脚本时,经常会遇到输出中文乱码,而这往往是因为输出的字符串本身编码与控制台编码不一致。 实例证明: #! -*- coding:utf-8 -*- a="中文" #定义一个变量,默认为Str,utf-8编码 print a print type(a) windows控制台输出结果: 浣犲ソ linux终端输出结果: 中文 linux url编码解码_linux编码_linux 默认编码 造成这种差异的原因在于windows控制台为gbk编码,而变量a本身为utf-8编码。 解决方案 #! -*- coding:utf-8 -*- a='你好' b=a.decode("utf-8").encode("gbk") print b 将变量a从utf-8编码转换为gbk编码。 python编码 python2.x从外部获取的内容都是string编码,其内部分为String编码与Unicode编码,而String编码又分为UTF-8,GBK,GB2312等等。因此为了避免不同编码造成的报错,python内部最好都转化为unicode编码,在输出时再转化为str编码 。可以用encode()/decode()函数,将string与unicode编码互换。 触发异常点 基本在于python内部变量编码与控制台编码,或者其他编码相结合时触发。 实例证明: #! -*- coding:utf-8 -*- a="中文" #定义一个变量,默认为str,utf-8编码 print a print type(a) 运行结果: 浣犲ソ 说明:windows下控制台输入输出都是gbk编码格式,而代码中定义的变量a为str,utf-8格式,所以会出现乱码。如果想创建一个unicode编码字符串的变量,则可以a=u”123”,在双引号前面加上一个u,表示a为unicode编码。 解决方案 #! -*- coding:utf-8 -*- a='你好' print a.decode("utf-8").encode("gbk") 说明:首先我们定义的变量a是str格式,编码为utf-8的字符串,我们要将之转化为str格式,GBK编码的字符串。在python内部无法直接转化,需要借助decod()与encode()函数。decode()函数先将str格式的字符串a转化为unicode,再将unicode编码为str格式GBK。而在Unix系统下,不存在这个问题,因为都是utf-8编码,不会存在乱码。print语句默认会将unicode编码的字符串,encode为相应系统的str编码并输出(windows下为gbk,unix下为utf-8),因此不用担心print unicode编码字符串会报错。 源代码编码 源代码编码指的是python程序本身的编码,默认为ascii。 触发异常点 python程序本身要被解释器解析执行,需要先被转化为二进制代码。而在这过程中容易引发异常,原因同样是ascii不支持中文,因此当python程序中出现中文时,哪怕是注释,也会引发ascii异常。 实例证明: print "中文" #中文注释 报错:SyntaxError: Non-ASCII character ‘\xe7’…… 解决方案 #! -*- coding:utf-8 -*- python程序开头加上这句代码,指定python源代码编码格式为utf-8。 文件编码 文件编码指的是,python程序从文件中获取的内容的编码格式。可以用sys.getfilesystemencoding()函数获取,windows下为mbcs,linux下为utf-8。至于mbcs,是一种多字节编码(没搞很明白)。 触发异常点(读取文件内容) 当python程序从文件中获取内容,并输出时,容易触发异常。 实例证明: #! -*- coding:utf-8 -*- f=open("test.txt","r") content=f.read() print type(content) print content 运行结果: 你好 可以看到windows下,从文件中读取的编码格式为Str,GBK格式(因为控制台输出没有中文乱码);而在Unix下为Str,Utf-8格式。从输出内容来说,并没有触发异常,然而当这些内容与python程序自身内容相结合时,容易触发异常。 解决方案 在windows下,最好将文件内容转为unicode,可以使用codecs: f=codecs.open("test.txt", encoding='gbk').read() 将格式为gbk的文件内容转化为unicode格式,当然也可以直接使用open(“”,”r”).read().decode(“gbk”) linux 默认编码_linux编码_linux url编码解码 触发异常点(写入文件内容) 参考操作系统编码触发异常点,即将中文unicode字符写入文件时,容易触发异常。 解决方案 参考操作系统编码解决方案,或者手动将unicode编码转换为str编码。 实例证明: #! -*- coding:utf-8 -*- a=u"中文" #a为unicode格式编码 f=open("test.txt","w") f.write(a.encode("gbk")) 当然如果变量a本身就是Str则不会报错,只是utf-8编码的内容写入windows文件中,显示会乱码。 网页编码 网页编码,通常在写爬虫的时候经常遇到,再结合系统编码,python编码,文件编码,往往会搞得一团乱。在程序中我们应该分别处理这些编码,在python内部全部转化为unicode。那么网页编码又有哪些格式呢? 常见格式:utf-8,gbk,gb2312 触发异常点 还是在于从网页中获取的源码编码与终端编码,甚至python内部编码不一致的情况。 实例证明: #!coding=utf-8 import urllib2 body=urllib2.urlopen('http://thief.one').read() print type(body) print body 运行结果: body中文显示乱码 说明:这个网站的编码是utf-8,而且python从网页上爬取的内容都为Str格式,在windows控制台下输出会乱码。 解决方案 依照之前做法,先将其转化为unicode。而相应的正则也可以为unicode编码,如:res=r’’+u”新成员”。可以通过chardet模块判断网页编码类型,返回的是一个带概率的字典。 编码判断判断字符串编码 isinstance(obj, (str, unicode)) 返回True或者False 判断网页编码 import chardet import urllib2 body=urllib2.urlopen("http://thief.one").read() chardet.detect(body) 判断编码格式,会有百分比,一般用来判断网页编码比较好。 判断系统编码 print sys.getdefaultencoding() #系统默认编码 print sys.getfilesystemencoding() #文件系统编码 print locale.getdefaultlocale() #系统当前编码 print sys.stdin.encoding #终端输入编码 print sys.stdout.encoding #终端输出编码 python2.x编码建议其他疑难杂症 实例一: a="\\u8fdd\\u6cd5\\u8fdd\\u89c4" print a 变量a的内容本身为unicode编码,怎么正常显示输入? 解决方案: a="\\u8fdd\\u6cd5\\u8fdd\\u89c4" # unicode转化为中文 b=a.decode('unicode-escape') print b 如果阅读完本章,增加了您对python编码问题的认识linux编码,那我会感到欣慰,如有python编码上的问题可以在下方留言。 如果阅读完本章,您仍然不知如何解决python乱码问题,没关系,请继续移步阅读Transcode解决python编码问题 为了能够让您重视,我不得不再次重申:解决python2.x编码问题的关键,在于要明白无论从哪里来的内容,在python内部流通时,都应该先转换为unicode。(python3.x在这方面做了改进,并取得了很好的效果) 技术的探索,就好像编织故事一般,其乐趣在于偶尔能够讲述给别人听,并获得一些赞同! (编辑:财气旺网 - 财气网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐

