快速入手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的Django框架编写从Google Adsense中获得报表的应用
Apr 17 Python
Python实现对象转换为xml的方法示例
Jun 08 Python
Python面向对象之继承和组合用法实例分析
Aug 27 Python
Python3 获取一大段文本之间两个关键字之间的内容方法
Oct 11 Python
python执行CMD指令,并获取返回的方法
Dec 19 Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
Jan 05 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
Mar 20 Python
给大家整理了19个pythonic的编程习惯(小结)
Sep 25 Python
python 解决flask 图片在线浏览或者直接下载的问题
Jan 09 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
Jan 18 Python
python十进制转二进制的详解
Feb 07 Python
10张动图学会python循环与递归问题
Feb 06 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
使用php4加速网络传输
2006/10/09 PHP
Apache2 httpd.conf 中文版
2006/11/17 PHP
对象失去焦点时自己动提交数据的实现代码
2012/11/06 PHP
ThinkPHP 3.2 数据分页代码分享
2014/10/14 PHP
PHP 获取ip地址代码汇总
2015/07/05 PHP
MAC下通过改apache配置文件切换php多版本的方法
2017/04/26 PHP
PHP实现的获取文件mimes类型工具类示例
2018/04/08 PHP
jquery的相对父元素和相对文档定位示例代码
2013/08/02 Javascript
JavaScript调试工具汇总
2014/12/23 Javascript
jQuery实现简单的日期输入格式化控件
2015/03/12 Javascript
JavaScript Function函数类型介绍
2015/04/08 Javascript
教你用javascript实现随机标签云效果_附代码
2016/03/16 Javascript
总结十个Angular.js由浅入深的面试问题
2016/08/26 Javascript
bootstrap table插件的分页与checkbox使用详解
2017/07/23 Javascript
vue 动态修改a标签的样式的方法
2018/01/18 Javascript
AngularJS模态框模板ngDialog的使用详解
2018/05/11 Javascript
Angular5中调用第三方库及jQuery的添加的方法
2018/06/07 jQuery
JS基于ES6新特性async await进行异步处理操作示例
2019/02/02 Javascript
vue axios封装及API统一管理的方法
2019/04/18 Javascript
webpack常用配置总览(小结)
2019/11/18 Javascript
jQuery实现简单聊天室
2020/02/08 jQuery
微信小程序文章详情功能完整实例
2020/06/03 Javascript
Vue Router中应用中间件的方法
2020/08/06 Javascript
Postman无法正常返回结果问题解决
2020/08/28 Javascript
python实现简单的TCP代理服务器
2014/10/08 Python
如何将python中的List转化成dictionary
2016/08/15 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
2016/10/12 Python
一文总结学习Python的14张思维导图
2017/10/17 Python
Django 连接sql server数据库的方法
2018/06/30 Python
对python:print打印时加u的含义详解
2018/12/15 Python
公司部门司机岗位职责
2014/01/03 职场文书
老同学聚会感言
2014/02/23 职场文书
公司会议开幕词
2015/01/29 职场文书
企业宣传稿范文
2015/07/23 职场文书
浅谈Nginx 中的两种限流方式
2021/03/31 Servers
Python图片处理之图片裁剪教程
2021/05/27 Python