快速入手Python字符编码

前言

对于很多接触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字符编码的全部内容,希望读完这篇文章能对大家能有帮助,有什么不足之处万望指正,希望大家多多支持我们。

(0)

相关推荐

  • Python中字符编码简介、方法及使用建议

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有英文,而单字节可以表示256个不同的字符,可以表示所有的英文字符和许多的控制符号.不过ASCII只用到了其中的一半(\x80以下),这也是MBCS得以实现的基础. 1.2. MBCS 然而计算机世界里很快就有了其他语言,单字节的ASCII已无法满足需求.后来每个语言就制定了一套自己的编码,由于单字节

  • Python字符编码判断方法分析

    本文实例讲述了Python字符编码判断方法.分享给大家供大家参考,具体如下: 方法一: isinstance(s, str) 用来判断是否为一般字符串 isinstance(s, unicode) 用来判断是否为unicode 或 if type(str).__name__!="unicode": str=unicode(str,"utf-8") else: pass 方法二: Python chardet 字符编码判断 使用 chardet 可以很方便的实现字符串

  • 详解Python当中的字符串和编码

    字符编码 我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节.比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295. 由于计算机是美国人发明的,因此,最早只有1

  • 基于python 字符编码的理解

    一.字符编码简史: 美国:1963年 ASCII (包含127个字符  占1个字节) 中国:1980年 GB2312 (收录7445个汉字,包括6763个汉字和682个其它符号) 1993年 GB13000 (收录20902个汉字) 1995年 GBK1.0 (收录 21003个汉字) 2000年 GB18030 (收录70244个汉字) 世界:1991年 unicode('万国码'也就统一编码,通常占2字节,复杂的汉字占4字节) UTF-8 (可变长的字符编码) 二.python中的编码解码应

  • 快速入手Python字符编码

    前言 对于很多接触Python的人而言,字符的处理和语言整体的温顺可靠相比显得格外桀骜不驯难以驾驭. 文章针对Python 2.7,主要因为3对的编码已经有了很大的改善并且实际原理一样,更改一下操作命令即可. 了解完本文,你可以轻松解决文字处理,特殊平台(Windows?)下的编码,爬虫编码等问题. 阅读建议 本文分为如下几个部分: 1.原理 2.具体操作 3.建议的使用习惯 4.疑难问题解答 如果想要了解我给出的使用习惯,可以直接跳到建议的使用习惯. 如果只想要解决相关问题可以直接跳到疑难问题

  • Python字符编码与函数的基本使用方法

    一.Python2中的字符存在的解码编码问题 如果是现在正在用Python2的人应该都知道存在字符编码问题,就举一个最简单的例子吧:Python2是无法在命令行直接打印中文的,当然他也是不会报错的,顶多是一堆你看不懂的乱码.如果想在直接显示中文,我们是可以在Python2文件头部申明字符编码的格式.如下图 这里 #-*-coding:utf-8 -*- 是用来申明下面的代码是用什么编码来解释: 1.1.Python2中的解码和编码: 在编码和解码的世界中,我们得需要找一个大家都知道的文字.也可以

  • 彻底搞懂Python字符编码

    不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError.UnicodeDecodeError 错误,每当遇到错误我们就拿着 encode.decode 函数翻来覆去的转换,有时试着试着问题就解决了,有时候怎么试都没辙,只有借用 Google 大神帮忙,但似乎很少去关心问题的本质是什么,下次遇到类似的问题重蹈覆辙,那么你有没有想过一次性彻底把 Python 字符编码给搞懂呢? 完全理解字符编码 与 Python 的渊源前,我们有

  • Python字符编码转码之GBK,UTF8互转

    一.Python字符编码介绍 1.须知: 在python 2中默认编码是 ASCII,而在python 3中默认编码是 unicode unicode 分为utf-32 (占4个字节),utf-16(占两个字节),utf-8(占1-4个字节),所以utf-16 是最常用的unicode版本,但是在文件里存的还是utf-8,因为utf8省空间 在python 3,encode编码的同时会把stringl变成bytes类型,decode解码的同时会把bytes类型变成string类型 在unicod

  • 浅析Python 字符编码与文件处理

    Python字符编码 目前计算机内存的字符编码都是Unicode,目前国内的windows操作系统采用的是gbk. python2默认的字符编码方式是ASCII python3默认的字符编码方式是Unicode .py文件头部的#coding:utf-8是帮助python识别.py文件的编码方式,故在写.py文件时要注意文件头和文件保存时的编码方式要相同,否则可能会出现乱码 python程序运行过程: python的解释器现在内存中启动 解释器把要运行的文件以文本文件的形式读进内存 解释器按照文

  • 关于Python字符编码与二进制不得不说的一些事

    二进制 核心思想: 冯诺依曼 + 图灵机 电如何表示状态,才能稳定? 计算机开始设计的时候并不是考虑简单,而是考虑能自动完成任务与结果的可靠性, 简单始终是建立再稳定.可靠基础上 经过尝试10进制,但很难检查电流的状态差异并且很难稳定状态,最稳定的检查是 通电和不通电状态,共两种状态那就规定 通电为 1 不通电 为 0,1和0的状态逻 辑被称为比特 Bit 那么如何用 0 和 1 表示数字和字符呢? 首先找出需要表示的字符,英文字符和数字字符才100多个,需要 7 个二进制位就 可以全部表示,但

  • 一篇文章彻底弄懂Python字符编码

    目录 1. 字符编码简介 1.1. ASCII 1.2. MBCS 1.3. Unicode 2. Python2.x中的编码问题 2.1. str和unicode 2.2. 字符编码声明 2.3. 读写文件 2.4. 与编码相关的方法 3.建议 3.1.字符编码声明 3.2. 抛弃str,全部使用unicode. 3.3. 使用codecs.open()替代内置的open(). 3.4. 绝对需要避免使用的字符编码:MBCS/DBCS和UTF-16. 1. 字符编码简介 1.1. ASCII

  • 深入浅析Python字符编码

    Python的字符串编码规则一直让我很头疼,花了点时间研究了下,并不复杂.主要涉及的内容有常用的字符编码的特点,并介绍了在python2.x中如何与编码问题作战,本文关于Python的内容仅适用于2.x,3.x中str和unicode有翻天覆地的变化,具体请查阅相关资料. 1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有英文,而单字节可以表示25

随机推荐