python基础:编码格式

一、Python解释器执行过程

1.启动Python解释器,相当于启动一个文本编辑器工具。

2.Python解释器打开Python的.py文件,从硬盘中将文件内容存储到内存中。

3.Python解释器执行内存中的.py代码。

总结:

  1. python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样。
  2. 与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内。

二、什么是字符编码

  计算机要想工作必须通电,也就是说‘电’驱使计算机干活,而‘电’的特性,就是高低电平(高低平即二进制数1,低电平即二进制数0),也就是说计算机只认识数字

 编程的目的是让计算机干活,而编程的结果说白了只是一堆字符,也就是说我们编程最终要实现的是:一堆字符驱动计算机干活

  所以必须经过一个过程:

  字符--------(翻译过程)------->数字 

  这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

三、字符编码介绍

ASCII:(American Standard Code for Information Interchange,美国标准信息交换代码),一个Bytes(位)代表一个字符,(英文字符/键盘上的所有其他字符,拉丁文,拉丁文),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符

GBK:(只支持中文),2Bytes代表一个字符,为了满足其他国家,各个国家纷纷定制了自己的编码,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr

unicode:(万国码,为了兼容各国统一编码,优点速度快内存中默认是unicode编码,缺点占用空间大),统一用2Bytes代表一个字符2**16-1=65535,可代表6万多个字符,因而兼容万国语言

utf-8:对于通篇都是英文的文本来说,这种编码方式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)于是产生了UTF-8,对英文字符只用1Bytes表示,对中文字符用3Bytes.

总结:

  1. 内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快)
  2. 硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。

ASSCII对应表

四、程序的执行

1.Python解释器读取代码第一行#coding:utf-8,这是规定编辑器以什么格式加载到内存中,规定Python解释器使用什么编码格式解析。

2.python2中默认使用ascii,python3中默认使用utf-8

3.内存的编码使用unicode,不代表内存中全都是unicode编码的二进制,

在程序执行之前,内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的

但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,比如x="egon",会被python解释器识别为字符串,会申请内存空间来存放"hello",然后让x指向该内存地址,此时新申请的该内存地址保存也是unicode编码的egon,如果代码换成x="egon".encode('utf-8'),那么新申请的内存空间里存放的就是utf-8编码的字符串egon了

浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器

如果服务端encode的编码格式是utf-8, 客户端内存中收到的也是utf-8编码的二进制。

Python2 的两种字符串类型str和unicode

str类型

当python解释器执行到产生字符串的代码时(例如s='林'),会申请新的内存地址,然后将'林'encode成文件开头指定的编码格式,这已经是encode之后的结果了,所以s只能decode,所以很重要的一点是:

在python2中,str就是编码后的结果bytes,str=bytes,所以在python2中,unicode字符编码的结果是str/bytes

复制代码
#coding:utf-8
s='林' #在执行时,'林'会被以conding:utf-8的形式保存到新的内存空间中

print repr(s) #'xe6x9ex97' 三个Bytes,证明确实是utf-8
print type(s) #<type 'str'>

s.decode('utf-8')
# s.encode('utf-8') #报错,s为编码后的结果bytes,所以只能decode
复制代码

unicode类型

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

复制代码
s=u'林'
print repr(s) #u'u6797'
print type(s) #<type 'unicode'>


# s.decode('utf-8') #报错,s为unicode,所以只能encode
s.encode('utf-8') 
复制代码

打印到终端

对于print需要特别说明的是:

当程序执行时,比如

x='林'

print(x) #这一步是将x指向的那块新的内存空间(非代码所在的内存空间)中的内存,打印到终端,而终端仍然是运行于内存中的,所以这打印可以理解为从内存打印到内存,即内存->内存,unicode->unicode

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

python3中的字符串与python2中的u'字符串',都是unicode,所以无论如何打印都不会乱码

在pycharm中

在windows终端

 

但是在python2中存在另外一种非unicode的字符串,此时,print x,会按照终端的编码执行x.decode('终端编码'),变成unicode后,再打印,此时终端编码若与文件开头指定的编码不一致,乱码就产生了

在pycharm中(终端编码为utf-8,文件编码为utf-8,不会乱码)

在windows终端(终端编码为gbk,文件编码为utf-8,乱码产生)

 

思考题:

分别验证在pycharm中和cmd中下述的打印结果

复制代码
#coding:utf-8
s=u'林' #当程序执行时,'林'会被以unicode形式保存新的内存空间中


#s指向的是unicode,因而可以编码成任意格式,都不会报encode错误
s1=s.encode('utf-8')
s2=s.encode('gbk')
print s1 #打印正常否?
print s2 #打印正常否


print repr(s) #u'u6797'
print repr(s1) #'xe6x9ex97' 编码一个汉字utf-8用3Bytes
print repr(s2) #'xc1xd6' 编码一个汉字gbk用2Bytes

print type(s) #<type 'unicode'>
print type(s1) #<type 'str'>
print type(s2) #<type 'str'>
复制代码

Python3 的两种两种字符串类型 str和bytes

str是unicode

复制代码
#coding:utf-8
s='林' #当程序执行时,无需加u,'林'也会被以unicode形式保存新的内存空间中,

#s可以直接encode成任意编码格式
s.encode('utf-8')
s.encode('gbk')

print(type(s)) #<class 'str'>
复制代码

 

bytes是bytes

复制代码
#coding:utf-8
s='林' #当程序执行时,无需加u,'林'也会被以unicode形式保存新的内存空间中,

#s可以直接encode成任意编码格式
s1=s.encode('utf-8')
s2=s.encode('gbk')



print(s) #林
print(s1) #b'xe6x9ex97' 在python3中,是什么就打印什么
print(s2) #b'xc1xd6' 同上

print(type(s)) #<class 'str'>
print(type(s1)) #<class 'bytes'>
print(type(s2)) #<class 'bytes'>
复制代码
原文地址:https://www.cnblogs.com/hanjialong/p/6861470.html