python 中文编码(一)
我在学python的过程中,遇到的第二个问题,就是中文乱码,如今也算勉强入门了,在这里给大家说说我的经验,也算个新人引导吧。
在文章里,我会重点提到一个概念:有来有去。
即数据从哪里来,到哪里去?
====================================================
1、windows下cmd终端中的中文
C:\Documents and Settings\admin>python
Python 2.7.7 (default, Jun 1 2014, 14:17:13) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '我是中文'
>>> ss = u'我真的是中文'
>>> s
'\xce\xd2\xca\xc7\xd6\xd0\xce\xc4'
>>> ss
u'\u6211\u771f\u7684\u662f\u4e2d\u6587'
>>> print s
我是中文
>>> print ss
我真的是中文
>>>
这样看来,输入和输出都不会出现乱码的,即使我们的字符串加了u。
1)输入从哪里来?
终端
2)输入是什么编码?
一个不知道,一个是unicode
3)输出是什么编码?
不知道
2.、windows下cmd中执行py文件
我们先来看看代码 test.py
#coding:utf-8
s = 'abc我是中文字符串'
ss = u'我也是中文字符串'
print s
print repr(s)
print ss
print repr(ss)
文件是以utf8 withour BOM形式存在的(后面我们再来讨论文件编码)。
我们在cmd终端中执行看看
D:\code>python test.py
abc鎴戞槸涓枃瀛楃涓
'abc\xe6\x88\x91\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87\xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2'
我也是中文字符串
u'\u6211\u4e5f\u662f\u4e2d\u6587\u5b57\u7b26\u4e32'
D:\code>
天啊,怎么会有乱码,怎么能有乱码!!我快疯了。
stop,先别疯,我们来一步一步分析:
1)输入从哪里来?
废话,从文件里来
2)输入是什么编码?
这个,好像一个是utf8,一个是unicode
3)输出是什么编码?
不知道哎,不是utf8么?
是不是看出一点点问题了?
utf8 ------> 输出编码 ---------> 出现乱码
unicode ------> 输出编码 ---------> 不出现乱码
那么那么,在文字输出之前,我们先转换为unicode,再输出,是不是就不会有乱码了呢?我们来试一试
#coding:utf-8
s = 'abc我是中文字符串'
ss = u'我也是中文字符串'
print s
print repr(s)
# 其它字符串解码成unicode
uu = s.decode('utf-8')
print uu
print repr(uu)
print ss
print repr(ss)
看看执行结果
D:\code>python test.py
abc鎴戞槸涓枃瀛楃涓
'abc\xe6\x88\x91\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87\xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2'
abc我是中文字符串
u'abc\u6211\u662f\u4e2d\u6587\u5b57\u7b26\u4e32'
我也是中文字符串
u'\u6211\u4e5f\u662f\u4e2d\u6587\u5b57\u7b26\u4e32'
D:\code>
果然没有乱码了。
看样子终于是解决了一点问题,但是,远远不够,因为我们还可能遇到其它的问题。
3、windows下cmd中与用户交互
为了应对各种环境,我们的代码会遭遇各种问题?
比如写好的代码可能会在cmd中执行,可能在idle中执行,也可能在linux下执行,我们要尽可能的控制程序按照我们的意愿来工作,第一个就是不出现乱码。
假如我们现在有一个代码文件,需要用户的输入,我们在cmd中执行,我们需要明确的知道一点,我们输入的编码是什么?
只有知道输入的编码是什么?才能进行解码成unicode,才能不出现乱码。
那么,在cmd中,输入的编码是什么?
在这之前,我们先来学习下decode和encode
1)decode 解码,在已知字符串编码的情况下,转码为unicode ,比如 s.decode('utf-8'),结果为unicode
2)encode 编码,在已有unicode的情况下,转码为其它编码,比如 u.encode('utf-8'),结果为utf-8
我只要说一点,你就懂了
sys.stdin.encoding
当然了,与之对应的是
sys.stdout.encoding
还是看看代码吧:
#coding:utf-8
import sys
s = raw_input()
print s
print repr(s)
u = s.decode(sys.stdin.encoding)
print u
print repr(u)
o = u.encode(sys.stdout.encoding)
print o
print repr(o)
cmd中运行
D:\code>python test.py
我是中文
我是中文
'\xce\xd2\xca\xc7\xd6\xd0\xce\xc4'
我是中文
u'\u6211\u662f\u4e2d\u6587'
我是中文
'\xce\xd2\xca\xc7\xd6\xd0\xce\xc4'
D:\code>
idle中运行
Python 2.7.7 (default, Jun 1 2014, 14:17:13) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
我是中文
我是中文
'\xce\xd2\xca\xc7\xd6\xd0\xce\xc4'
我是中文
u'\u6211\u662f\u4e2d\u6587'
我是中文
'\xce\xd2\xca\xc7\xd6\xd0\xce\xc4'
>>>
linux中运行
root@kali:~/Desktop# python test.py
我是中文
我是中文
'\xe6\x88\x91\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87'
我是中文
u'\u6211\u662f\u4e2d\u6587'
我是中文
'\xe6\x88\x91\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87'
总结:
如果你知道你从哪里来,要到哪里去,你一定会到达那个地方。