python 之字符编码

一了解字符编码的储备知识python解释器和文件本编辑的异同相同点:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样不同点:文本编辑器

大家好,又见面了,我是你们的朋友全栈君。

 一    了解字符编码的储备知识

python解释器和文件本编辑的异同

     相同点:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样

     不同点:文本编辑器将文件内容读入内存后,是为了显示/编辑,而python解释器将文件内容读入内存后,是为了执行(识别python语法)

二  什么是字符编码

字符编码的定义:

所谓的字符编码就是让计算机读懂人类语言的字符

字符编码产生的过程

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

字符编码的涉及场景

 1. 一个python文件中的内容是由一堆字符组成的(python文件未执行时)

 2. python中的数据类型字符串是由一串字符组成的(python文件执行时)

三  字符编码发展史

阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII 

阶段二:为了满足中文,中国人定制了GBK(其他各国为了满足各国的发展需求纷纷制定了自己的字符编码)

阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

<span role="heading" aria-level="2">python 之字符编码
<span role="heading" aria-level="2">python 之字符编码

于是产生了unicode, 统一用2Bytes代表一个字符, 2**16-1=65535,可代表6万多个字符,因而兼容万国语言

但对于通篇都是英文的文本来说,这种编码方式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)

于是产生了UTF-8,对英文字符只用1Bytes表示,对中文字符用3Bytes。unicode 和UTF-8各有优劣

unicode:简单粗暴,所有字符都是2Bytes,优点是字符->数字的转换速度快,缺点是占用空间大

utf-8:精准,对不同的字符用不同的长度表示,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表示

****    所有程序,最终都要加载到内存,程序保存到硬盘不同的国家用不同的编码格式,但是到内存中我们为了兼容万国(计算机可以运行任何国家的程序原因在于此),统一且固定使用unicode,这就是为何内存固定用unicode的原因,你可能会说兼容万国我可以用utf-8啊,可以,完全可以正常工作,之所以不用肯定是unicode比utf-8更高效啊(uicode固定用2个字节编码,utf-8则需要计算),但是unicode更浪费空间,没错,这就是用空间换时间的一种做法,而存放到硬盘,或者网络传输,都需要把unicode转成utf-8,因为数据的传输,追求的是稳定,高效,数据量越小数据传输就越靠谱,于是都转成utf-8格式的,而不是unicode。

解决乱码的方法

四 字符编码的类型

ASCII码:

ASCII码是字符编码的鼻祖最早诞生于西方世界,只限于西方世界使用

Unicode码:

又称为万国编码,解决了ASCII码的缺陷,但是占用的内存相对较大

UTF-8:

延续了万国编码的传统,但是解决了万国编码占用内存大的问题

GBK:

只限于中国内部使用的字符编码

各类型字符编码之间的关系

ASCII码是字符编码的鼻祖最早诞生与西方世界,因为只局限与西方世界使用所以诞生了unicode在世界范围内都可以使用但因为占用内存较大所以又诞生了utf-8解决了占用内存较大的问题

Bit,bytes,kb,Mb,GB,TB之间的转换:

8Bit=1 Bytes1024bytes=1Kb1024Kb=1 mb1024mb=1 GB1024GB=1TB

 位和字节的关系

位是最小的二进制内存单位   字节是最小的字符单位 一个字节bytes等于8个位bit

unicode  utf-8  gbk编码之间的转换:

编码格式           英文            中文Unicode           4               4 utf-8             1               3gbk               1               2

字节和字符串的转换

字符串转换为字节

s = 'hello workd'
res = bytes(s,encoding='utf-8')
print(res)

字节转换为字符串

s = bytes'hello workd'
res = str(s,encoding='utf-8')
print(res)

五  字符编码的使用

文本编译器(以notepadd++为例)

<span role="heading" aria-level="2">python 之字符编码

当我们用编译器编译一段对我们有用的信息并且关闭之后   当我们需要的时候打开之后却发现所编译的内容和之前的完全不一样了   会出现大量的乱码。那么为什么会有乱码呢?

一 存文件时就已经乱码

存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,

本质上其他国家的文字由于在shiftjis中没有找到对应关系而导致存储失败,用open函数的write可以测试,f=open(‘a.txt’,’w’,encodig=’shift_jis’)

f.write(‘你瞅啥\n何を見て\n’) #’你瞅啥’因为在shiftjis中没有找到对应关系而无法保存成功,只存’何を見て\n‘可以成功

但当我们用文件编辑器去存的时候,编辑器会帮我们做转换,保证中文也能用shiftjis存储(硬存,必然乱码),这就导致了,存文件阶段就已经发生乱码

此时当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了

二 存文件时不乱码而读文件时乱码

存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了,而存文件时乱码,则是一种数据的损坏。

怎么防止乱码出现?

无论是何种编辑器,要防止文件出现乱码(请一定注意,存放一段代码的文件也仅仅只是一个普通文件而已,此处指的是文件没有执行前,我们打开文件时出现的乱码)

核心法则就是,文件以什么编码保存的,就以什么编码方式打开

decodeh和encode

首先要搞清楚,字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码, 即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码

import sys
'''
*首先要搞清楚,字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,
即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。
总得意思:想要将其他的编码转换成utf-8必须先将其解码成unicode然后重新编码成utf-8,它是以unicode为转换媒介的
如:s='中文'
如果是在utf8的文件中,该字符串就是utf8编码,如果是在gb2312的文件中,则其编码为gb2312。这种情况下,要进行编码转换,都需要先用
decode方法将其转换成unicode编码,再使用encode方法将其转换成其他编码。通常,在没有指定特定的编码方式时,都是使用的系统默认编码创建的代码文件。
如下:
s.decode('utf-8').encode('utf-8')
decode():是解码
encode()是编码
isinstance(s,unicode):判断s是否是unicode编码,如果是就返回true,否则返回false*

'''
'''
s='中文'
s=s.decode('utf-8')   #将utf-8编码的解码成unicode
print isinstance(s,unicode)   #此时输出的就是True
s=s.encode('utf-8')           #又将unicode码编码成utf-8
print isinstance(s,unicode)   #此时输出的就是False
'''
print sys.getdefaultencoding()

s='中文'
if isinstance(s,unicode):   #如果是unicode就直接编码不需要解码
    print s.encode('utf-8')
else:
    print s.decode('utf-8').encode('gb2312')

print sys.getdefaultencoding()    #获取系统默认的编码
reload(sys)
sys.setdefaultencoding('utf8')    #修改系统的默认编码
print sys.getdefaultencoding()

python2和python3中的字符编码

python2

             str类型 ----------->字节编码后的二进制数据      
   
    字符串类型
                 
                      unicode类型-------->unicode编码后的二进制数据
 
s1=''
  
print type(s1) # <type 'str'>
print repr(s1) #'\xe8\x8b\x91
  
s2=u''
print type(s2) # <type 'unicode'>
print repr(s2) # u'\u82d1'
 
 
 
s1=u''
print repr(s1) #u'\u82d1'
 
b=s1.encode('utf8')
print b
print type(b)  #<type 'str'>
print repr(b)  #'\xe8\x8b\x91'
 
s2='苑昊'
u=s2.decode('utf8')
print u        # 苑昊
print type(u)  # <type 'unicode'>
print repr(u)  # u'\u82d1\u660a'
 
#注意
u2=s2.decode('gbk')
print u2  #鑻戞槉
 
print len('苑昊') #6

python3

              str类型 ---------->unicode编码后的二进制数据      
   
    字符串类型
                 
                      bytes类型-------->bytes编码后的二进制数据
 
import json
 
s='苑昊'
print(type(s))       #<class 'str'>
print(json.dumps(s)) #  "\u82d1\u660a"
 
b=s.encode('utf8')
print(type(b))      # <class 'bytes'>
print(b)            # b'\xe8\x8b\x91\xe6\x98\x8a'
 
u=b.decode('utf8')
print(type(u))       #<class 'str'>
print(u)             #苑昊
print(json.dumps(u)) #"\u82d1\u660a"
 
print(len('苑昊')) # 2

相关练习

<span role="heading" aria-level="2">python 之字符编码
<span role="heading" aria-level="2">python 之字符编码

字符编码:
 
---utf8存入硬盘-------
 
#coding:utf8
print("坏小子")
---------------------
 
方式一:在pycharm执行  setting都是utf8
 
python 3  不乱码
python 2  不乱码
 
方式二:在cmd执行
 
python 3  不乱码    解释器按utf8解码,翻译为uniode在执行,cmd执行print("坏小子")时,字符串为unicode数据
 
python 2  乱码      解释器按utf8解码,翻译为bytes在执行,cmd应该把"坏小子"打印为bytes数据,而不是明文
                   但python2解释器会进行一个暗转换,把"坏小子" bytes数据解码转换为unicode数据,
                   cmd按gbk将bytes数据解码为unicode时,会出错。

View Code

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/124532.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SIGINT信号

    SIGINT信号原文链接 http hi baidu com l1l1888 blog item 9024a2fe75c6 html 用户按下 ctrl c 时 进程被中断 catch 被执行 中断处理函数处理完毕 root localhost001 catsigint demo cpp include include includeusing st

    2025年7月15日
    5
  • Linux CentOS 7安装Oracle11g超完美教程[通俗易懂]

    Linux CentOS 7安装Oracle11g超完美教程[通俗易懂]Oracle部署文章目录Oracle部署1基本环境介绍2检测是否安装了Oracle3卸载Oracle3.1重新做一次虚拟机3.2卸载Oracle4安装准备4.1建立oracle用户和用户组4.2为Oracle的安装创建相关目录4.3优化OS内核参数4.4限制oracle用户的shell权限4.5为Oracle用户添加Oracle环境变量4.6配置hostname(本机IP映射)4.7安装VNC&Oracle相关依赖4.7.1配置yum源4.7.2安装依赖4.7.3检

    2022年7月15日
    19
  • Java中创建对象数组[通俗易懂]

    Java中创建对象数组[通俗易懂]1.对象数组的概念:如果一个数组中的元素是对象类型,则称该数组为对象数组。当需要一个类的多个对象时,应该用该类的对象数组来表示,通过改变下标值就可以访问到不同的对象。2.对象数组的定义和使用:对象数组的定义与一般数组的定义类似,但是需要为每一个元素实例化。3.对象数组的实例化:类名[]对象数组名=new类名[数组大小]以创建Student类的对象数组为例Student[]stu=newStudent[20];//创建20个学生对象对学生类的每一个数组元素进行

    2022年7月16日
    57
  • xml转为excel_excel表格怎么转换xml格式

    xml转为excel_excel表格怎么转换xml格式旧版的excel文件OfficeXML是xml类型的,也成为SpreadsheetML类型,很古老的excel类型了是2002年左右的格式,现在的格式都是用的xls或者xlsx。遇到的问题就是要把xml类型的OfficeXML转化为xlsx的excel,所以写了本篇文章方便以后遇到这个问题的人。(注意,本文的代码只支持横向的单元格合并,纵向合并的单元格因为会受到横向合并的单元格而对不齐)二、解析类SAXHandler类XmlConvertExcel类XmlRow类三、测试

    2022年8月22日
    6
  • http协议与tcp协议区别[通俗易懂]

    http协议与tcp协议区别[通俗易懂]http协议与tcp协议区别1、性质不同:http是一个简单的请求-响应协议。TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。2、连接不同:TCP连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。http通常运行在TCP之上。指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。3、功能不同:当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网

    2026年1月30日
    2
  • Ubuntu下安装yum和配置yum源

    Ubuntu下安装yum和配置yum源1、简介Yum(全称为YellowdogUpdater,Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装2、安装yum2.1检测是否安装build-essential包sudoapt-getinstallbuild-essential或者apt-getinstallbuil.

    2022年6月20日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号