Python中文虐我千百遍,我待Python如初恋。本文主要介绍在Python2/3交互模式下,通过对中文、英文的处理输出,理解Python的字符编码与解码问题(以点破面)。
前言:字符串的编码一开始是 ascii,只支持英文,由于多种语言的存在,出现万国码 unicode,但 unicode 不兼容 ascii,而且对存储空间造成浪费,所以出现 utf-8 编码,一种针对 unicode 的可变长度字符编码。
Python3的字符编码与解码输出
>>> hi = b'hello, world'
>>> hi
b'hello, world'
>>> print(hi)
b'hello, world'
>>> hi.decode('utf-8')
'hello, world'
>>> hey = '你好'
>>> hey
'你好'
>>> print(hey)
你好
>>> unihey = hey.encode('unicode_escape')
>>> unihey
b'\\u4f60\\u597d'
>>> print(unihey)
b'\\u4f60\\u597d'
>>> unihey.decode('unicode_escape')
'你好'
>>> '\u4f60\u597d'
'你好'
在 Python3 中共有两种字符序列。一种是 str 序列,默认对字符串编码;一种是 bytes 序列,操作二进制数据流,如代码段一中的 hi,通过在字符串前的 b,即表示 bytes 。这两种序列可通过 decode 和 encode 相互转换,如下图:
在代码段一中,通过对 bytes 以 utf-8 的格式解码,得到 str。除此之外,还可通过 unicode_escape、gbk 等格式解码;
在代码段二中,通过对 str 的中文 hey 以 unicode_escape 的格式编码,得到 bytes 。用什么格式编码就用什么解码,即可得到原字符。
由于 Python3 对中文的支持友好,将 unihey 中的转义符 \ 去掉,在交互模式下可直接显示中文。
在网络传输中,如 urllib、request 等获取数据的库,通常返回 bytes 序列,这时可通过 decode 指定相应的格式经行解码,获取中文字符。
Python2的字符编码与解码输出
>>> hi = u'hello, world'
>>> hi
u'hello, world'
>>> print hi
hello, world
>>> hi.encode('utf-8')
'hello, world'
>>> hi.encode('unicode_escape')
'hello, world'
>>> hey = '你好'
>>> hey
'\xc4\xe3\xba\xc3'
>>> print hey
你好
>>> uhey = u'你好'
>>> uhey
u'\u4f60\u597d'
>>> print uhey
你好
>>> ghey = uhey.encode('gbk')
>>> ghey
'\xc4\xe3\xba\xc3'
>>> print ghey
你好
>>> hey.decode('gbk')
u'\u4f60\u597d'
>>> print hey.decode('gbk')
你好
>>> '\u4f60\u597d'
'\\u4f60\\u597d'
在 Python2 中也有两种字符序列。一种是 unicode 序列,如代码段一中的 hi,通过在字符串前的 u,即表示 unicode,相当于 Python3 中的 str;一种是 str 序列,相当于 Python3 中的 bytes 。这两种序列可通过 decode 和 encode 相互转换,如下图:
在代码段一中,通过对 unicode 以 utf-8、unicode_escape 的格式编码,得到 str;
在代码段二中,通过对 str 的中文 hey 以 gbk 的格式解码,得到 unicode;对 unicode 的中文 uhey 以 gbk 的格式编码,得到 str 。
在 Python 的交互模式下,直接输出是 Python 所理解的代码中的状态,而 print 输出的是给用户看到。
从代码段二的20行、21行可以看出,Python2 对中文的支持没有 Python3 友好。除此之外,当列表中有中文时,Python2 必须遍历列表,才能在交互模式下看到中文,而 Python3 直接打印列表即可。
总结
上述表述可能不到位,欢迎交流讨论!同时我们可以通过 Anaconda 切换不同的 Python 环境,去尝试上述小栗子,随便编码解码,玩坏了算我输~( ̄▽ ̄)~
随机推荐
三分之一的程序猿之社交类app踩过的那些坑
三分之一的程序猿之社交类app踩过的那些坑 万众创新,全民创业.哪怕去年陌生人社交不管融资与否都倒闭了不知道多少家,但是依然有很多陌生人社交应用层出不穷的冒出来.各种脑洞大开,让人拍案叫起. 下面我们 ...
In Action(SPFA+01背包)
In Action Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
android 控件描边取消重叠
今天写组件的时候用到了描边.可是两个组件放在一起时,描边会变重叠,使之变粗.就不是很美观了. 如何取消呢?网上查了好久没找到,然后就自己试了试,找到了解决方法,就在此记录一下,防止以后忘记. 很简单分 ...
Maven Jrebel 多模块热部署方案
近期在构建maven多模块项目时,发现web module依赖的其它模块,每次都要clean install成一个jar包,然后运行web module才能加载. 本生jrebel是配置在了web m ...
printf详解
用了这么多年c了,今天想编个小程序练练手,忽然发现对于printf这个函数并不甚了解.上网查了查,下面是对printf()的详解: 函数原型: #include int ...
第四章 FFmpeg转码
4.1 FFmpeg软编码H.264与H.265 4.1.1 x264编码参数简介 4.1.2 H.264编码举例
出现System.web.mvc冲突的原因及解决方法CS0433
1.问题描述 CS0433:类型“System.Web.Mvc.WebViewPage”同时存在于URL1和URL2中 2.解决方案 找到Web.config文件中的< ...
Maven 学习笔记——Maven和Eclipse(2)
前面已经配置好Maven的环境和本地仓库已经准备好了,下面我们通过Eclipse创建Maven项目. 1.安装Maven集成于Eclipse IDE (Eclipse的版本中如果已经集成了Maven插 ...
设计模式之模板方法模式&;&;迪米特法则(代码Objective-C展示)
模板方法模式 模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变一个算法的结构即可重定义该算法的某些特定步骤. 比如说,小时候数学老师的随堂检测,都是在黑板 ...
手撕vue-cli配置——webpack.prod.conf.js篇
'use strict' const path = require('path') const utils = require('./utils') const webpack = require(' ...