博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊一聊 Python 2 中的编码
阅读量:6885 次
发布时间:2019-06-27

本文共 2042 字,大约阅读时间需要 6 分钟。

hot3.png

在 Python 尤其是 Python2 中,编码问题是困扰开发者尤其初学者的一大问题。什么 Unicode/UTF-8/str ,又是 decode/encode 的,搞得人头都大了。其实不然,这有点类似 Java 中 java.io 包一样,看似庞大难懂,但是可以非常精细地定制需求。

屏幕快照 2016-03-01 16.30.04.png

编码

计算机只可以存储和处理二进制数据,所以从文字到计算机可以识别的二进制之间需要一道对应关系。于是便有了ASCII(American Standard Code for Information Interchange,美国标准信息交换代码),ASCII使用7位二进制数标记了128(2**7)字符(符号、字母、控制符等),由于1byte=8bit,所以干脆最高位补个0,凑够8位以方便计算和处理。

接着,拉丁语系的技术宅们发现,这128个字符的高位空着的,那么干脆用来表示拉丁语系的主要符号吧,还是使用单字节,但是可以表示的字符数量增加了一倍。这套编码叫做latin-1(iso-8859-1)。

这些宅男们没有想到,区区一个字节256个符号,对于东亚国家来讲,简直呵呵了。拿中文为例,仅常用字符就几千个,于是中国国家标准总局制定了一套中文编码——GB2312。GB2312通过两个字节表示一个汉字,且最高位为0的部分兼容ASCII,最高位为1的部分则通过连续的两个字节表示一个中文字。后来又出现了兼容GB2312的GBK编码。

到这里,依然面临了一个问题:GB2312或者GBK编码中,仅可以表示汉字和英文字符,无法做到多语言文字同时表示。这时候,Unicode(又称万国码)出现了。Unicode采用32位二进制(4字节)表示一个字符,这样便可以一套编码对应多种不同语言。Unicode是一种编码,它的作用是指定字符到二进制数之间的对应关系。但是对于存储和传输,Unicode有几种不同的实现,比较常用的是UTF-8、UTF-16、UTF-32。UTF-32中,每个字符固定占4字节,按照Unicode编码完全映射。而UTF-8和UTF-16则属于变长编码,分别使用最少1个(UTF-8)或2个(UTF-16)字节到最多4个字节来编码。

Python源码的编码

Python2中,如果在源码首行(或在指定sha-bang时的第二行)不显式指定编码,则无法在源码中出现非ASCII字符。这是由于Python解释器默认将源码认作ASCII编码格式。PEP263()中约定,可以通过如下方式之一来声明源码的编码格式:

# coding=
# or# -*- coding:
-*- # or# vim: set fileencoding=
:

Python中的编码

Python中有两个常用的由basestring派生出来的表示字符串的类型:str,unicode。其中,str类似于C中的字符数组或者Java中的byte数组,事实上你可以将它理解为一个存储二进制内容的容器,str不存储编码信息,如果对str类型的字符串迭代的话,则会按照其在内存中的字节序依次迭代,意味着如果这个字符串存储的是多字节字符(Unicode/GBK等),则会截断这个字符,演示如下:

屏幕快照 2016-03-01 16.15.08.png

而对于unicode类型,Python在内存中存储和使用的时候是按照UTF-8格式,在代码中的表示为字符串前加u,如:

屏幕快照 2016-03-01 16.23.18.png

unicodestr之间的转换,则用到了encodedeocde方法。decode表示将一个(str)字符串按照给定的编码解析为unicode类型,encode则表示将一个unicode字符串按照指定编码解析为字节数组(str):

屏幕快照 2016-03-01 16.26.11.png

屏幕快照 2016-03-01 16.30.04.png

文件读写

内置的open函数打开文件时,read方法读取的是一个str(私以为叫做字节数组更合适),如果读取的是其它编码的文字,则需要decode之后再做使用。

屏幕快照 2016-03-01 16.54.33.png

对于使用open函数打开文件之后的写操作(多字节编码的字符串),则需要将需要写入的字符串按照其编码encode为一个str,如果直接写入,则会引发如下错误(如果在代码中加入了encoding声明,则会按照声明的编码格式encode后写入):

屏幕快照 2016-03-01 16.56.06.png

除此以外,codecs模块也提供了一个open函数,可以直接指定好编码打开一个文本文件,那么读取到的文件内容则直接是一个unicode字符串。对应的指定编码后的写入文件,则可以直接将unicode写到文件中。通过codecs.open可以避免很多编码问题:

屏幕快照 2016-03-01 17.02.53.png

建议

对于Python代码中避免遇到编码问题,有一些小建议:

  • 字符编码声明:在代码开头声明编码格式
  • 使用codecs的open函数处理文本文件
  • 尽可能使用unicode而不是str:在所有字符串的引号前加u

转载于:https://my.oschina.net/liuyuantao/blog/712030

你可能感兴趣的文章
linux配置网卡
查看>>
正则表达式语法
查看>>
013、Dockerfile构建镜像(2019-01-02 周三)
查看>>
c# mvc如何获取xml文件
查看>>
mongodb Java(八)
查看>>
JavaScript随机数
查看>>
ASP.NET验证控件——RequiredFieldValidator
查看>>
strstr
查看>>
MySQL 条件 select case 的实现(解决 零 做分母的问题 )
查看>>
openNebula rgister img instance vms error collections
查看>>
error Infos
查看>>
PL/sql配置相关
查看>>
接着浅析table-cell的简单应用
查看>>
Project 10:简单图像的绘制
查看>>
(第五条)避免创建不必要的对象
查看>>
MongoDB的快速手动安装
查看>>
面试常见问题(转载)
查看>>
洛谷P3306 随机数生成器
查看>>
《平凡的世界》中田晓霞和孙少平的爱情
查看>>
【资源共享】《DDR常见问题简单排查》
查看>>