一、字符编码应用之Python

1.1 执行Python程序的三个阶段

Python test.py(我再强调一遍,执行test.py的第一步,一定是先将文件内容从硬盘读入到内存中)

test.py文件内容以gbk格式保存的,内容为:

  • 阶段一:启动Python解释器
  • 阶段二:Python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中

此时,Python解释器会读取test.py的第一行内容,#coding:utf-8#-*-coding:utf-8-*-,以此决定以什么编码格式将代码读入内存,这一行就是设定Python解释器这个软件使用的编码格式。

可以用sys.getdefaultencoding()查看,如果不在Python文件指定头信息#-*-coding:utf-8-*-,那就使用Python默认的编码格式。

import sys

sys.getdefaultencoding()
'utf-8'

Python2中默认使用ascii,Python3中默认使用utf-8。

改正:在test.py指定文件头,字符编码一定要为gbk。即更正为

#coding:gbk
你好啊

  • 阶段三:读取已经加载到内存的代码(Unicode编码格式),然后执行,执行过程中可能会开辟新的内存空间,比如name="nick"

内存的编码使用Unicode,不代表内存中全都是Unicode,因为在程序执行之前,内存中确实都是Unicode,比如从文件中读取了一行name="nick",其中的name、等号、引号的地位都一样,都是普通字符而已,都是以Unicode的格式存放于内存中的。

但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间)用来存放Python的数据类型的值,而Python的字符串类型又涉及到了字符的概念。

比如name="nick",会被Python解释器识别为字符串,会申请内存空间来存放字符串类型的值,至于该字符串类型的值被识别成何种编码存放,这就与Python解释器的有关了,而Python2与Python3的字符串类型又有所不同。

二、Python2与Python3字符串类型的区别

2.1 Python2

在Python2中有两种字符串类型str和Unicode。

2.1.1 str类型

当Python解释器执行到产生字符串的代码时(例如x='上'),会申请新的内存地址,然后将'上'编码成文件开头指定的编码格式

因为直接print()会自动转换编码,我们使用encode()方法查看'上'的字符编码。

# 三、Python2中代码

# 四、coding:gbk

x = '上'
y = '下'
print([x, y]) # ['\xc9\xcf', '\xcf\xc2']
# 五、\x代表16进制,此处是c9cf总共4位16进制数,一个16进制四4个比特位,4个16进制数则是16个比特位,即2个Bytes,这就证明了按照gbk编码中文用2Bytes print(type(x),type(y)) # (<type 'str'>, <type 'str'>)

理解字符编码的关键!!!

内存中的数据通常用16进制表示,2位16进制数据代表一个字节,如\xc9,代表两位16进制,一个字节

gbk存中文需要2个bytes,而存英文则需要1个bytes,它是如何做到的???!!!

gbk会在每个bytes,即8位bit的第一个位作为标志位,标志位为1则表示是中文字符,如果标志位为0则表示为英文字符。

x='你a好'

转成gbk格式二进制位:8bit+8bit+8bit+8bit+8bit=(1+7bit)+(1+7bit)+(0+7bit)+(1+7bit)+(1+7bit)

这样计算机按照从左往右的顺序读:

  1. 连续读到前两个括号内的首位标志位均为1,则构成一个中午字符:你
  2. 读到第三个括号的首位标志为0,则该8bit代表一个英文字符:a
  3. 连续读到后两个括号内的首位标志位均为1,则构成一个中午字符:好

也就是说,每个Bytes留给我们用来存真正值的有效位数只有7位,而在Unicode表中存放的只是这有效的7位,至于首位的标志位与具体的编码有关,即在Unicode中表示gbk的方式为:(7bit)+(7bit)+(7bit)+(7bit)+(7bit)

按照上图翻译的结果,我们可以去Unicode关于汉字的对应关系中去查:链接:https://pan.baidu.com/s/1dEV3RYp

可以看到“上”对应的gbk(G0代表的是gbk)编码就为494F,即我们得出的结果,而上对应的Unicode编码为4E0A,我们可以将gbk-->decode-->Unicode。

# 六、Python2中代码

# 七、coding:gbk

x = '上'.decode('gbk')
y = '下'.decode('gbk')
print([x, y]) # [u'\u4e0a', u'\u4e0b']

7.0.2 Unicode类型

当Python解释器执行到产生字符串的代码时(例如s=u'林'),会申请新的内存地址,然后将'林'以Unicode的格式存放到新的内存空间中,所以s只能encode,不能decode。

# 八、Python2中代码

# 九、coding:gbk

x = u'上'  # 等同于 x='上'.decode('gbk')
y = u'下' # 等同于 y='下'.decode('gbk')
print([x, y]) # [u'\u4e0a', u'\u4e0b']
print(type(x),type(y)) # (<type 'Unicode'>, <type 'Unicode'>)

对于print需要特别说明的是:当程序执行时,比如x='上' # gbk下,字符串存放为\xc9\xcf

print(x)这一步是将x指向的那块新的内存空间(非代码所在的内存空间)中的内存,打印到终端,按理说应该是存的什么就打印什么,但打印\xc9\xcf,对一些不熟知Python编码的程序员,立马就懵逼了,所以龟叔自作主张,在print(x)时,使用终端的编码格式,将内存中的\xc9\xcf转成字符显示,此时就需要终端编码必须为gbk,否则无法正常显示原内容:上。

对于Unicode格式的数据来说,无论怎么打印,都不会乱码

Unicode这么好,不会乱码,那Python2为何还那么别扭,搞一个str出来呢?Python诞生之时,Unicode并未像今天这样普及,很明显,好的东西你能看得见,龟叔早就看见了,龟叔在Python3中将str直接存成Unicode,我们定义一个str,无需是否加u前缀,就是一个Unicode,屌不屌?

9.1 Python3

Python3中str都是Unicode编码的,所以Python3中的str类型的数据可以编码成其他字符编码的格式,编码的结果为bytes类型。

# coding:gbk
x = '上' # 当程序执行时,无需加u,'上'也会被以Unicode形式保存新的内存空间中, print(f"type(x): {type(x)}") # <class 'str'> # x可以直接encode成任意编码格式
print(f"x.encode('gbk'): {x.encode('gbk')}") # b'\xc9\xcf'
print(f"type(x.encode('gbk')): {type(x.encode('gbk'))}") # <class 'bytes'>
type(x): <class 'str'>
x.encode('gbk'): b'\xc9\xcf'
type(x.encode('gbk')): <class 'bytes'>

很重要的一点是:看到Python3中x.encode('gbk') 的结果\xc9\xcf正是Python2中的str类型的值,而在Python3是bytes类型,在Python2中则是str类型。

总而言之

代码详情 Python2执行情况 Python3执行情况
# coding:gbk
print('中')
终端:utf8
乱码 不乱码
# coding:utf8
print('中')
终端:utf8
不乱码 不乱码
# coding:gbk
print(u'中')
终端:utf8
不乱码 不乱码
# coding:utf8
print(u'中')
终端:utf8
不乱码 不乱码

在Python2中如果指定了字符编码,那么内存存取就会按照指定的字符编码去入内存。解释或去执行时就要按照指定了的字符编码去解释,否则就会乱码。 否则可以在定义变量前面加上u,这样变量就会以unicode编码存入内存。

如:

#coding:gbk

name = "爸爸"

但在Python3中就不会有这样的问题,因为无论你指定了什么字符编码,在内存存取时都会使用Unicode编码去入内存,Unicode编码可以和任意的字符编码相互转换,并在读取时按照所需的编码区读取,这样就很好解决了字符编码的问题

Python2与Python3字符编码的区别的更多相关文章

  1. day008 字符编码之 字符编码 、Python2和Python3字符编码的区别

    计算机基础(掌握) 启动应用程序的流程 双击qq 操作系统接受指令然后把该操作转化为0和1发送给CPU CPU接受指令然后把指令发送给内存 内存接受指令把指令发送给硬盘获取数据 qq在内存中运行 文本 ...

  2. Python2和3字符编码的区别

    Python2和3字符编码的区别 一.字符编码应用之Python 1.1 执行Python程序的三个阶段 Python test.py(我再强调一遍,执行test.py的第一步,一定是先将文件内容从硬 ...

  3. 第六篇.文件处理之python2和3字符编码的区别

    目录 python2和3字符编码的区别 一.字符编码应用之python python2和3字符编码的区别 一.字符编码应用之python 1执行python的三个阶段 python test.py 执 ...

  4. 50-Python2和3字符编码的区别

    目录 Python2和3字符编码的区别 python2 python3 Python2和3字符编码的区别 区别点 python2 python3 print 是一个语法结构 是一个函数,print(' ...

  5. 字符编码 + python2和python3的编码区别(day08整理)

    目录 昨日回顾 二十三.元组内置方法 二十四.散列表 二十五.字典内置方法 二十六.集合内置方法 二十七.深浅拷贝 拷贝 浅拷贝 深拷贝 今日内容 二十八.字符编码 1.文本编辑器存储信息的过程 2. ...

  6. Python2.7 中文字符编码 & Pycharm utf-8设置、Unicode与utf-8的区别

    Python2.7 中文字符编码 & Pycharm utf-8设置.Unicode与utf-8的区别 zoerywzhou@163.com http://www.cnblogs.com/sw ...

  7. python2与python3 字符问题以及 字符编码 内容总结

    python2与python3默认编码: python2:gbk                   print( u'上' )     操作系统也是 gbk    python3:unicode p ...

  8. Python2和Python3的一些语法区别

    Python2和Python3的一些语法区别 python 1.print 在版本2的使用方法是: print 'this is version 2 也可以是 print('this is versi ...

  9. ASCII、Unicode、GBK和UTF-8字符编码的区别联系(转载)

    ASCII.Unicode.GBK和UTF-8字符编码的区别联系 转载自:http://dengo.org/archives/901 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同 ...

随机推荐

  1. linux下安装xhprof

    https://jingyan.baidu.com/article/a24b33cd7ee1d519ff002b6d.html

  2. Java Elasticsearch新手入门教程

    概要: 1.使用Eclipse搭建Elasticsearch详情参考下面链接 2.Java Elasticsearch 配置 3.ElasticSearch Java Api(一) -添加数据创建索引 ...

  3. 【Quartz】常用方法的使用方式(三)

    前言    总结了一下quartz组件的一些常用方法,以备将来不时之需.哈哈,看着挺简单有些好是值得笔记一下的.好记性不如烂笔头吗? 代码部分: 方法类内容: public class Example ...

  4. C# 插入、删除Excel分页符

    引言 对Excel表格设置分页对我们预览.打印文档时是很方便的,特别是一些包含很多复杂数据的.不规则的表格,为保证打印时每一页的排版美观性或者数据的前后连接的完整性,此时的分页符就发挥了极大的作用.因 ...

  5. PyCharm下载及安装教程

    pycharm官网地址 https://www.jetbrains.com/pycharm/download/#section=windows 下载社区版 选择安装路径E:\Python\pychar ...

  6. DropZone(文件上传插件)

    1. html文件 dropzone的原理是模拟表单来上传文件,html中的元素有多重形式. 可以建立一个form表单: <form id="dropz" action=&q ...

  7. golang自定义路由控制实现(二)-流式注册接口以及支持RESTFUL

        先简单回顾一下在上一篇的文章中,上一篇我主要是结合了数组和Map完成路由映射,数组的大小为8,下标为0的代表Get方法,以此类推,而数组的值则是Map,键为URL,值则是我们编写对应的接口.但 ...

  8. OAuth 2 开发人员指南(Spring security oauth2)

    https://github.com/spring-projects/spring-security-oauth/blob/master/docs/oauth2.md 入门 这是支持OAuth2.0的 ...

  9. python基础下的mysql学习之操作命令(一)

    E-R模型简介: 该模型应用于数据库设计中的概念结构设计阶段 E-entry,实体,是指设计的主体.对象等: R-relationship,关系,是指设计的主体之间的联系,关系也是一种数据: 一个实体 ...

  10. ubuntu16.04如何安装搜狗输入法

    1 . 首先我们需要先来下载支持linux版本的搜狗输入法安装包,这里我们先查看下自己的ubuntu系统是什么版本的,这里我们可以在右上角的那个齿轮图标点击查看"系统设置",在里面 ...