python基础篇10-py2和py3编码

编码基础

编码概述 

基本概念很简单。首先,我们从一段信息即消息说起,消息以人类可以理解、易懂的表示存在。我打算将这种表示称为“明文”(plain text)。对于说英语的人,纸张上打印的或屏幕上显示的英文单词都算作明文。其次,我们需要能将明文表示的消息转成另外某种表示,我们还需要能将编码文本转回成明文。从明文到编码文本的转换称为“编码”,从编码文本又转回成明文则为“解码”。

python解释器在加载 .py 文件中的代码时,会对内容进行编码。python2 默认编码方式是ascii码,python3 默认编码方式utf-8。

ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 = 256-1,所以,ASCII码最多只能表示 255 个符号。

编码方式

ascii:只能支持英文、特殊字符、数字,用一个字节表示一个字符。最多只能表示 255 个符号;

万国码(unicode):所有的字符和符号由4个字节来表示。占资源较多;(早期所有字符使用2个字节表示,现在已经废弃)

UTF-8:是对Unicode的升级。UTF-8最少使用一个字节表示一个字符。一个字节表示一个英文字符、2个字节表示一个欧洲字符、3个字节表示一个亚洲字符;

gbk:是国人在 ascii 码的基础上进行升级的,只支持中文和英文,2个字节表示一个中文字符,1个字节表示一个英文字符。

注意:各个编码之间的二进制是不能互相识别的,会产生乱码;文件的存储和传输不能是Unicode编码方式,因为Unicode占资源较多,只能使用utf8-8、utf8-16、gbk、gb2312、ascii等编码方式才能存储和传输;各个编码之间的转换可以通过unicode这个中间过程进行转换。(utf8-8、utf8-16、gbk、gb2312、ascii等编码方式统称为bytes)

编码解码

编码 encode:将str数据类型转化成bytes数据类型

解码 decode:将bytes数据类型转化成str数据类型

字节串:bytes;字符串:unicode

python2编码

python2编码

Python2有两种数据类型:str和unicode。str数据类型在内存中是用bytes编码方式存储的(bytes是utf8-8、utf8-16、gbk、gb2312、ascii等编码方式的统称)。

#!-*- coding:utf-8 -*-
#__author: lriwu
#date 2018/5/8

# str 在内存中使用bytes编码方式存储
s1 = "测试hello"
print len(s1)      # 11
print repr(s1)     # ‘\xe6\xb5\x8b\xe8\xaf\x95hello‘
print type(s1)     # <type ‘str‘>

# unicode存的是unicode,即字符串
s2 = u"测试hello"
print len(s2)      # 7
print repr(s2)     # u‘\u6d4b\u8bd5hello‘
print type(s2)     # <type ‘unicode‘>

python2编码的最大特点:Python2 将会自动的将bytes数据解码成 unicode 字符串

print "测试"  # 测试,即可以显示中文。正常情况下其实不应该显示中文,而应该是字节串,之所以显示中文,原因是在py 2中自动的将bytes数据类型解码成 unicode 字符串
print "hello"+u"yuan"  # helloyuan ,即byte和unicode可以进行拼接,Python 2 将会自动的将bytes数据解码成 unicode 字符串

两个问题:

1、print "测试" :本来存的是‘\xe8\x8b\x91\xe6\x98\x8a‘,为什么显示了明文?

正常情况下其实不应该显示中文,而应该是字节串(bytes),之所以显示中文,原因是在py 2中自动的将bytes数据解码成 unicode 字符串。

2、字节串和字符串可以拼接?

这就是那些可恶的 UnicodeError 。代码中包含了 unicode 和 byte 字符串,只要数据全部是 ASCII 的话,所有的转换都是正确的,一旦一个非 ASCII 字符偷偷进入你的程序,那么默认的解码将会失效,从而造成 UnicodeDecodeError 的错误。Python 2 悄悄掩盖掉了 byte 到 unicode 的转换,让程序在处理 ASCII 的时候更加简单。你复出的代价就是在处理非 ASCII 的时候将会失败。

print "测试"+u"文本"   #字节串和字符串进行拼接

E:\soft_install\python\python2.7\python2.exe F:/code/test.py
Traceback (most recent call last):
  File "F:/code/test.py", line 5, in <module>
    print "测试"+u"文本"
UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe6 in position 0: ordinal not in range(128)

编码解码

#coding:utf8

u = u‘苑‘
print repr(u)  # u‘\u82d1‘
# print str(u)   #UnicodeEncodeError

s = u.encode(‘utf8‘)
print repr(s) #‘\xe8\x8b\x91‘
print str(s)  #  苑
u2 = s.decode(‘utf8‘)
print repr(u2) # u‘\u82d1‘

str和unicode都是basestring的子类。严格意义上说,str其实是字节串,它是unicode经过编码后的字节组成的序列。对UTF-8编码的str‘苑‘使用len()函数时,结果是3,因为utf8编码的‘苑‘ == ‘\xe8\x8b\x91‘;

而unicode是一个字符串,str是unicode这个字符串经过编码(通过utf8或gbk编码)后的字节组成的序列;

unicode才是真正意义上的字符串,对字节串str使用正确的字符编码进行解码后获得,并且len(u‘苑‘) == 1。

python3编码

python3编码

跟 Python2 类似,Python3 也有两种数据类型:unicode和bytes。但是他们有不同的命名。在py3中,将unicode重命名为str,将str重命名为bytes。即python3中两种数据类型是:str数据类型和bytes数据类型。str数据类型内存中是用unicode编码方式存储的,不能进行文件的存储和传输;bytes数据类型在内存中是用utf8-8、utf8-16、gbk、gb2312、ascii等编码方式存储的,进行文件的存储和传输需要转化成bytes数据类型。

对于英文:
str表现形式:s = ‘alex‘
str在内存中的编码方式:0101010101   unicode编码方式

bytes表现形式:s = b‘alex‘
bytes在内存中的编码方式:0101010101   utf-8 gbk等编码方式
例子
s = ‘alex‘
s1 = b‘alex‘
print(s,type(s))         //alex  <class ‘str‘>
print(s1,type(s1))     //b‘alex‘ <class ‘bytes‘>

对于中文:
str表现形式:s = ‘中国‘
str在内存中的编码方式:0101010101   unicode编码方式

bytes表现形式:s = b‘\xe4\xb8\xad\xe5\x9b\xbd‘
bytes在内存中的编码方式:0101010101   utf-8 gbk等编码方式
例子
s = ‘中国‘
print(s,type(s))         //alex  <class ‘str‘>
s1 = b‘中国‘             //这里会报错
print(s1,type(s1))     //b‘alex‘ <class ‘bytes‘>

对于中文和英文的表现形式

编码解码

编码 encode:将str数据类型转化成bytes数据类型;

解码 decode:将bytes数据类型转化成str数据类型。

编码例子:

s1 = ‘alex‘
s11 = s1.encode(‘utf-8‘)   #将str转换成utf-8
print(s11)  #  b‘alex‘

s2 = ‘中国‘
s22 = s2.encode(‘utf-8‘)
s33 = s2.encode(‘gbk‘)
print(s22,type(s22))    # b‘\xe4\xb8\xad\xe5\x9b\xbd‘ <class ‘bytes‘>
print(s33,type(s33))    # b‘\xd6\xd0\xb9\xfa‘ <class ‘bytes‘>
#总结:utf-8一个中文字符用3个字节,gbk一个中文字符用2个字节表示

编码实现

编码实现

说到编码,我们需要在全局掌握这个工作过程,比如我们在pycharm上编写一个.py文件,从保存到运行数据到底是怎么转换的呢?在解决这个问题之前,我们需要解决一个问题:默认编码,默认编码其实就是你的解释器解释代码时默认的编码方式,在py2里默认的编码方式是ASCII,在py3里则是utf8。(可以使用sys.getdefaultencoding()查看默认的编码方式):

#-*- coding: UTF-8 -*-

我们在最开始只知道在py2里如果不加上述这一句话,程序中有中文就会报错,其实就是因为py2默认的ASCII码,对于中文这些特殊字符无法编码。声明这句话就是告诉python2.7解释器解释hello.py文件时使用utf8编码,而不是使用默认的ASCII编码方式,将文件编码成字节串最后转成0101的形式让机器去执行;

hello.py文件保存时有自己特定的编码方式,比如utf8,比如gbk。声明使用的编码方式必须与文件实际保存时使用的编码方式一致,否则很大几率会出现代码解析异常(即在.py文件中声明解释器编码时使用utf8编码方式,此时.py文件保存时也要使用utf8编码方式保存至磁盘)。现在的IDE一般会自动处理这种情况,改变声明后同时换成声明的编码方式保存,但当使用操作系统上的文本编辑器编辑文本时需要小心,文件保存的编码方式取决于你使用的编辑器默认的样式(可调);

出现乱码的情况

案例1:

#!-*- coding:utf-8 -*-
#__author: lriwu

s = "特斯拉"
print (s)

F:\code>python test.py
特斯拉

#在cmd下使用python3编译,可以正常显示。
正常显示条件:
1. py文件是以utf8编码方式存储,解释器也是以utf8编码方式对.py文件进行编译;
2.打印的内容要在终端显示,在python3中字符串是str类型,在内存中是以unicode编码方式存储。所以cmd(windows默认使用gbk编码)能够识别该unicode编码,所以能够正常显示。(unicode所有的编码方式都能识别)

#!-*- coding:utf-8 -*-
#__author: lriwu

s = "特斯拉"
print (s)

F:\code>python2 test.py
鐗规柉鎷

#在cmd下使用python2编译,不能正常显示。
不能显示原因:
1. py文件是以utf8编码方式,解释器也是以utf8编码方式对.py文件进行编译。这个满足;
2.打印的内容要在终端显示,在python2中字符串是str类型,在内存是以bytes编码方式存储(这里是以utf8编码方式存储)。所以cmd(windows默认使用gbk编码)不能够识别该utf8编码,所以不能正常显示。

实现在py2上正常显示:

#!-*- coding:utf-8 -*-
#__author: lriwu

print (u‘"特斯拉"‘)

F:\code>python2 test.py
"特斯拉"

案例2:

在py2中正常显示

f = open(‘ces‘,‘r‘)
print (f.read())

E:\soft_install\python\python2.7\python2.exe F:/code/test.py

测试

# open(‘ces‘,‘r‘)这个是调用操作系统命令执行,所以使用的是windows默认的gbk编码。在py2中会自动的将gbk编码后的bytes数据解码成 unicode 字符串。

在py3上显示乱码

f = open(‘ces‘,‘r‘)
print (f.read())

E:\soft_install\python\python2.7\python2.exe F:/code/test.py

娴嬭瘯

#open(‘ces‘,‘r‘)这个是调用操作系统命令执行,所以使用的是windows默认的gbk编码。gbk编码后的bytes数据类型在pycharm中无法通过utf8的方式进行解码,所以显示乱码。

在py3上正常显示

f = open(‘ces‘,‘r‘,encoding=‘utf8‘)
print (f.read())

E:\soft_install\python\python3.5\python.exe F:/code/test.py

测试

#在这里声明windows打开文件时使用utf8方式编码,而不是使用windows默认的gbk进行编码。

原文地址:https://www.cnblogs.com/lriwu/p/9020577.html

时间: 2024-08-03 12:25:00

python基础篇10-py2和py3编码的相关文章

python 基础篇 10 函数进阶

本节主要内容:1. 函数参数--动态传参2. 名称空间, 局部名称空间, 全局名称空间, 作?域, 加载顺序.3. 函数的嵌套4. gloabal, nonlocal关键字 ?. 函数参数--动态传参之前我们说过了传参, 如果我们需要给?个函数传参, ?参数?是不确定的. 或者我给?个函数传很多参数, 我的形参就要写很多, 很?烦, 怎么办呢. 我们可以考虑使?动态参数.形参的第三种: 动态参数动态参数分成两种 ::: 1--->>>动态接收位置参数 首先,先回顾依稀位置参数: 注意:动

工程脚本插件方案 - c集成Python基础篇

工程脚本插件方案 - c集成Python基础篇 序: 为什么要集成脚本,怎么在工程中集成Python脚本. 在做比较大型的工程时,一般都会分核心层和业务层.核心层要求实现高效和稳定的基础功能,并提供调用接口供业务层调用的一种标准的框架划分.在实际中根据需求会拆分的更细. 外部的表现形式就是一个核心动态库,带着一堆业务业务动态库.通过一个调度程序把这些链接起来,外加一堆配置文件,就形成一个完成的项目. 这种模式在一个团队开发中,工作职责比较容易划分.制定API接口后,开发工作基本可以并行实现,包括

python基础篇(二)

python基础篇(二) if:else,缩进和循环控制 A:if的基础格式和缩进 B:循环判断 C:range()函数和len()函数 D:break,contiue和pass语句 for,while循环 函数基础 A:函数的定义和返回值 B:返回值的三种情况 C:函数的注释 函数的进阶(命名空间和作用域) A:内置命名空间 B:全局命名空间 C:局部命名空间 D:全局作用域 E:局部作用域 F:函数的嵌套和作用域链. G:函数名的本质 闭包 ?一:if:else和缩进 A:if的基础格式和缩

Python基础篇(八)

key words:私有变量,类静态变量,生成器,导入Python模块,r查看模块可以使用的函数,查看帮助信息,启动外部程序,集合,堆,时间模块,random模块,shelve模块,文件读取等 >>> class Rectangle: ...     def __init__(self): ...         self.__width = 0 ...         self.__height = 0 ...     def setSize(self,width,height): .

Python基础篇(七)

加上两个下划线变量或者方法变为私有. >>> class Bird: ...    __song = "spark" ...    def sing(self): ...       return self.__song ... >>> b = Bird() >>> b.sing() 'spark' >>> b.__sing() Traceback (most recent call last): File &qu

Python基础篇(五)

bool用于判断布尔值的结果是True还是False >>> bool("a") True >>> bool(3) True >>> bool("") False >>> bool(0) False Python中的elif类似于Java中的elseif >>> number = (int)(input("input a number: ")) input

python基础篇(五)

python基础篇(五) 算法初识 什么是算法 二分查找算法 ?一:算法初识 A:什么是算法 根据人们长时间接触以来,发现计算机在计算某些一些简单的数据的时候会表现的比较笨拙,而这些数据的计算会消耗大量计算机资源,而且耗时,这个时候就有人对这类计算编写了一些策略,这些策略就是算法.这些策略会加快数据计算时间,大大减少计算机的资源消耗. 在长时间人们编写代码的工作中,一些优秀的算法就被流传下来,但是不是所有的算法都能实现目的一步到位的工作,它只能减少你的代码,提高工作效率,随着知识的不断积累,你会

老王python基础篇--python, 视频, 教程, 视频教程, 基础

老王python基础篇 基础篇11-python基本数据结构-元组和集合.rar 基础篇19-python语句与数据结构应用.rar 基础篇21-文本操作应用.rar 基础篇3-虚拟机安装xubuntu开发环境.rar 基础篇17-python语句1.2.rar 基础篇10-python基本数据结构-列表应用.rar 基础篇9-python基本数据结构-列表.rar 基础篇5-python基本数据类型讲解1.1.rar 基础篇18-基础篇综合习题.rar 基础篇8-python基本数据类型习题解

python基础篇

python基础篇 变量命名 >>> name_value='freddy' 1 >>> name_value=freddy 2 Traceback (most recent call last): 3 File "<stdin>", line 1, in <module> 4 NameError: name 'freddy' is not defined **变量的值如果是字符串必须要加引号,否则定义变量会报错 (因为他把变

python模块之lib2to3(py2转py3自动化工具)

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python模块之lib2to3(py2转py3自动化工具) #http://tieba.baidu.com/p/3939904893 #操作步骤: 1.需要转换test.py文件为py3代码 #test.py文件放置在Scripts目录下,如果test.py文件不放置在Scripts目录下则 -w后面写完整的路径 #如: C:\python27\Tools\Scripts>2to3.py -w C:\P