快速入手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爬虫常用的模块分析
Aug 29 Python
初步解析Python下的多进程编程
Apr 28 Python
python基于socket实现网络广播的方法
Apr 29 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
Jun 01 Python
python 类的继承 实例方法.静态方法.类方法的代码解析
Aug 23 Python
Python PyInstaller库基本使用方法分析
Dec 12 Python
python绘制封闭多边形教程
Feb 18 Python
解决python Jupyter不能导入外部包问题
Apr 15 Python
python如何编写win程序
Jun 08 Python
如何使用pycharm连接Databricks的步骤详解
Sep 23 Python
详解Flask开发技巧之异常处理
Jun 15 Python
yolov5返回坐标的方法实例
Mar 17 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上传图片、删除图片实现代码
2010/05/12 PHP
PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
2011/06/04 PHP
php获取linux命令结果的实例
2017/03/13 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
2019/05/27 PHP
laravel csrf排除路由,禁止,关闭指定路由的例子
2019/10/21 PHP
两个比较有用的Javascript工具函数代码
2010/02/17 Javascript
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
document.documentElement和document.body区别介绍
2013/09/16 Javascript
JS获取各种浏览器窗口大小的方法
2014/01/14 Javascript
Javascript设计模式之观察者模式(推荐)
2016/03/29 Javascript
Bootstrap选项卡与Masonry插件的完美结合
2016/07/06 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
2016/09/18 Javascript
js实现表格筛选功能
2017/01/18 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
2017/03/23 Javascript
jQuery EasyUI之验证框validatebox实例详解
2017/04/10 jQuery
js实现延迟加载的几种方法
2017/04/24 Javascript
深入理解vuex2.0 之 modules
2017/11/20 Javascript
深入理解vue中slot与slot-scope的具体使用
2018/01/26 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
2018/10/10 Javascript
在 Vue.js中优雅地使用全局事件的方法
2019/02/01 Javascript
在Python中处理字符串之isdigit()方法的使用
2015/05/18 Python
Python中的默认参数详解
2015/06/24 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
用tensorflow构建线性回归模型的示例代码
2018/03/05 Python
对python pandas 画移动平均线的方法详解
2018/11/28 Python
如何利用Pyecharts可视化微信好友
2019/07/04 Python
python的一些加密方法及python 加密模块
2019/07/11 Python
Mountain Warehouse澳大利亚官网:欧洲家庭户外品牌倡导者
2016/11/20 全球购物
介绍一下木马病毒的种类
2015/07/26 面试题
医药代表个人的求职信分享
2013/12/08 职场文书
生物科学专业职业规划书范文
2014/02/11 职场文书
新闻发布会活动策划方案
2014/09/15 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
2015年消费者权益日活动总结
2015/02/09 职场文书
大学生自荐书范文
2015/03/05 职场文书