快速入手Python字符编码


Posted in Python onAugust 03, 2016

前言

对于很多接触Python的人而言,字符的处理和语言整体的温顺可靠相比显得格外桀骜不驯难以驾驭。

文章针对Python 2.7,主要因为3对的编码已经有了很大的改善并且实际原理一样,更改一下操作命令即可。

了解完本文,你可以轻松解决文字处理,特殊平台(Windows?)下的编码,爬虫编码等问题。

阅读建议

本文分为如下几个部分:

    1.原理

    2.具体操作

    3.建议的使用习惯

    4.疑难问题解答

如果想要了解我给出的使用习惯,可以直接跳到建议的使用习惯。

如果只想要解决相关问题可以直接跳到疑难问题解答。

希望本文能够帮到你。

原理

为了理解方便,这里不谈理论只做类比,具体想要进一步了解各种编码的理论的百度一下好了。

首先说一下我们为什么会碰到各式各样的编码问题:

    1.因为我们没有统一编码

    2.因为我们没有用对命令(传对数据)

再说一下编码是什么,Python的编码看似复杂,实际上可以看做只有两类编码:Unicode,二进制

     1.Unicode 相信都很熟悉:,就是\u0000这样的

     2.二进制编码也很简单,就是\x00\x00这样的,平常看到的utf-8,cp936都是二进制编码

     3.二进制编码是具象的10001100原样就可以存储,而Unicode是抽象的,不能这样存

#coding=utf8

# Unicode编码演示
print('Unicode:')
print(repr(u'Unicode编码'))`

# 二进制编码演示
print(u'二进制编码:')
print(repr('Unicode编码'))`

# 只是看个样子,代码不必去深究

再说怎么做,就是只有同种编码之间才可以操作

举个简单的类比

     就把一串数据比为烤鸭,我们作为人和鸭子不同种看待烤鸭的态度完全不一样。

     我们看到的是晚上的配菜,鸭子看到的是自己二舅。

     那么我在逛烤鸭店的时候用错编码就会报错。

     因为我在烤鸭店看到了满世界的二舅。

这里说的同种就是我们熟悉的各种编码方式:utf-8,unicode,ucs-bom

这也就是编码问题的核心,非常重要。

最后说一下Python的环境

    1.本身代码是用Ascii解码的,文件里有Ascii无法解码的内容的话要告知Python怎么解码

    2.内部大量命令都是默认接受Unicode

# 告知的命令就是下面这一行,删掉就会报错
#coding=utf8
print(u'测试编码')

具体操作

拿到各种编码的内容自然是不用说,那么如果我们想要自己构造怎么做呢,看下面:

#coding=utf8

# 字符串前面加u会默认构造出Unicode的字符串
unicodeString = u'Unicode字符串'

# 字符串前面什么都不加会构造出默认编码(首行限定了现在的utf8)的字符串
utf8String = 'Utf-8字符串'

# 当然,没有首行,默认的编码是Ascii

那么他们之间怎么转换呢,同样很简单:

# 接上一段程序

# Unicode转化为二进制编码中的一种:utf8
unicodeString.encode('utf8')

# 二进制编码根据自己的编码种类转化为Unicode
utf8String.decode('utf8')

# 如果二进制编码中混进了奇怪的东西可以根据需求用特殊的decode策略
print(repr('u8字\x00符串'.decode('utf8', 'replace')))

那么怎么样会出现问题呢:

# 接上一段程序

# 如果我们把他们转化成同样的编码方式就可以操作(例如相加)
print(repr(unicodeString + utf8String.decode('utf8')))
print(repr(unicodeString.encode('utf8') + utf8String))

# 但如果不转化,当然就会出现满世界的烤鸭二舅啦
unicodeString + utf8String

# 所以另一方面也发现,编码转换是需要我们告诉程序怎么做的
# 所有`decode`操作都会生成Unicode编码,这是为了方便我之前说的大量接受Unicode的内部命令

所以我们需要确定程序使用的编码,这是我们需要告诉程序的东西

    1.一方面在操作字符串的时候确定是同种编码

    2.另一方面在使用非自己写的命令时,一般使用Unicode,或者使用接收二进制编码的命令

#coding=utf8
# 这里拿写入文件举例

# 一般使用Unicode
with open('Unicode.txt', 'w') as f: f.write(u'Unicode测试')

# 或者使用接收二进制编码的命令
with open('Utf8.txt', 'wb') as f: f.write('Utf8测试')

# 你可以反过来做个测试,自然会报错
# 二进制的命令方便了在不知道怎么解码的情况下也能进行操作(写入文件)

我建议的使用习惯

相信到这里我已经把我对于编码的理解讲完了。

我们为什么会碰到各式各样的编码问题:

    1.因为我们没有统一编码

    2.因为我们没有用对命令(传对数据)

所以这里再重申一下八字真言:确定编码,同类交互

    1.碰到问题,问一下自己,我现在是哪种编码

    2.同一种编码才能交互,那我应该是哪种编码

这里给出我的使用习惯:

    1.确定一种内部编码

    2.内部编码的选择优先级如下:程序必须使用的编码、第三方包使用的编码、你喜欢的编码、Unicode

    3.在输出时再更改到特定的编码

记得在开始整个程序之前确定内部的编码,否则编码一团糟会产生很多不必要的bug。

不要迷信内部Unicode,例如Evernote开发就应该根据第三方包使用的Utf8确定内部编码。

疑难问题解答

编码识别

说了要确定编码,那么拿到一串二进制要怎么确定编码呢?

最简单的方法是chardet:(需要安装)

python -m pip install chardet

使用非常简单:

#coding=utf8

from chardet import detect
print(detect('这是一串utf8的测试字符'))

# 结果:`{'confidence': 0.99, 'encoding': 'utf-8'}`

另外例如抓取网站,那么头文件中很有可能有提示如何解码,记得不要忘记了。

编码转换

很可能因为字符串中参杂了奇怪的东西,导致即使编码种类正确,依旧无法解码。

我知道我之前讲过了,但可能有人直接跳疑难问题解答嘛。

这里可以使用decode的第二个参数:

#coding=utf8

# 字符串中混进了\x00
rubbishUtf8String = 'Utf-8字\x00符串'

print(repr(rubbishUtf8String.decode('utf8', 'replace')))

print(repr(rubbishUtf8String.decode('utf8', 'ignore')))

特殊平台下编码

很多人都说Windows是个坑,即使在Python 3下面也一样。

因为中文文件名出来都是乱码。

这里使用一个取巧的方法:平台编码再特殊,起码命令行读取和创建一个文件夹不会出乱码吧。

import sys, os

for folder in os.walk('.').next()[1]:
  print(folder.decode(sys.stdin.encoding))

同样的输入输出也可以这样做优化:

import sys

def sys_print(msg):
  print(msg.encode(sys.stdin.encoding))

def sys_input(msg):
  return raw_input(msg.encode(sys.stdin.encoding)).decode(sys.stdin.encoding)

文件写入

如果抓下来一个内容不知道怎么解码,但还是想要写入文件怎么办

写入文件的时候制定用二进制命令即可:

#coding=utf8
import urllib

with open('Utf8.txt', 'wb') as f: f.write('Utf8测试')

# 比如抓了个网页,不知道编码也可以写入文件进行一系列操作

content = urllib.urlopen('http://www.baidu.com').read()
with open('baidu.txt', 'wb') as f: f.write(content)

裸Unicode字符

Unicode存成六个Ascii字符怎么办?其实也可以decode

#coding=utf8
# 这是普通的Unicode
s = u'测'
for i in s: print(i)
print(repr(s))

# 这是裸Unicode,实际存成了六个Ascii
s = repr(s)[2:-1]
for i in s: print(i)
print(repr(s))

# 转化其实也很简单
s = s.decode('unicode-escape')
for i in s: print(i)
print(repr(s))

总结

以上就是详细介绍Python字符编码的全部内容,希望读完这篇文章能对大家能有帮助,有什么不足之处万望指正,希望大家多多支持三水点靠木。

Python 相关文章推荐
Python编程之多态用法实例详解
May 19 Python
浅谈python装饰器探究与参数的领取
Dec 01 Python
Python管理Windows服务小脚本
Mar 12 Python
python 数字类型和字符串类型的相互转换实例
Jul 17 Python
python中将\\uxxxx转换为Unicode字符串的方法
Sep 06 Python
实例讲解Python3中abs()函数
Feb 19 Python
Python 中pandas索引切片读取数据缺失数据处理问题
Oct 09 Python
tensorflow 查看梯度方式
Feb 04 Python
利用python在excel中画图的实现方法
Mar 17 Python
django 链接多个数据库 并使用原生sql实现
Mar 28 Python
python手机号前7位归属地爬虫代码实例
Mar 31 Python
Python之Matplotlib绘制热力图和面积图
Apr 13 Python
Python采用Django制作简易的知乎日报API
Aug 03 #Python
利用Python实现图书超期提醒
Aug 02 #Python
Python正规则表达式学习指南
Aug 02 #Python
Python实现SMTP发送邮件详细教程
Mar 02 #Python
python logging 日志轮转文件不删除问题的解决方法
Aug 02 #Python
python中的字典使用分享
Jul 31 #Python
Python随机生成数据后插入到PostgreSQL
Jul 28 #Python
You might like
基于PHP的简单采集数据入库程序
2014/07/30 PHP
PHP基于phpqrcode生成带LOGO图像的二维码实例
2015/07/10 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
php中namespace及use用法分析
2016/12/06 PHP
PHP连续签到功能实现方法详解
2019/12/04 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
Jquery 基础学习笔记
2009/05/29 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
2015/12/13 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
2016/01/23 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
node.js实现回调的方法示例
2017/03/01 Javascript
MUI 解决动态列表页图片懒加载再次加载不成功的bug问题
2017/04/13 Javascript
jQuery初级教程之网站品牌列表效果
2017/08/02 jQuery
关于vue.js发布后路径引用的问题解决
2017/08/15 Javascript
Angular实现的日程表功能【可添加及隐藏显示内容】
2017/12/27 Javascript
vue.js 微信支付前端代码分享
2018/02/10 Javascript
Vue-cli配置打包文件本地使用的教程图解
2018/08/02 Javascript
jQuery超简单遮罩层实现方法示例
2018/09/06 jQuery
el-select数据过多懒加载的解决(loadmore)
2019/05/29 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
2020/06/02 Javascript
详解nginx配置vue h5 history去除#号
2020/11/09 Javascript
[03:02]生活中的Dendi之野外度假篇
2016/08/09 DOTA
Python去掉字符串中空格的方法
2014/03/11 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
2019/12/19 Python
Django缓存Cache使用详解
2020/11/30 Python
CSS3新增布局之: flex详解
2020/06/18 HTML / CSS
约瑟夫·特纳男装:Joseph Turner
2017/10/10 全球购物
实习生单位鉴定意见
2013/12/04 职场文书
活动志愿者自荐信
2014/01/27 职场文书
学生宿舍管理制度
2014/01/30 职场文书
科技工作者先进事迹
2014/08/16 职场文书
推普标语口号大全
2015/12/26 职场文书
2019XX公司员工考核管理制度!
2019/08/07 职场文书
基于JavaScript实现省市联动效果
2021/06/22 Javascript
Java字符缓冲流BufferedWriter
2022/04/09 Java/Android