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

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • springboot的介绍_springboot web

    springboot的介绍_springboot webSpringboot入门介绍一、Spring框架概述1.1什么是SpringSpring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由RodJohnson在其著作《ExpertOne-On-OneJ2EEDevelopmentandDesign》。Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的Ja…

  • java bufferedwriter 关闭_Java BufferedWriter.close()方法示例

    java bufferedwriter 关闭_Java BufferedWriter.close()方法示例JavaBufferedWriter.close()方法示例BufferedWriter的JavaBufferedWriter.close()方法的语法如下。publicvoidclose()throwsIOException示例在下面的代码中展示了如何使用BufferedWriter.close()方法。importjava.io.BufferedWriter;import…

  • c语言中字符串比较的库函数是什么_c语言比较字符串大小

    c语言中字符串比较的库函数是什么_c语言比较字符串大小在单片机串口实现字符串命令解析这篇文章中分析了在串口通信中如何去解析字符串命令,这篇文章就来讨论下字符串比较的方法都有哪些?说起比较运算,肯定第一时间想到了C语言中关于比较的相关运算符“>、<、!=、>=、<=、==”,那么要比较两个字符串是否相等是不是直接用“==”比较就行了。下面就来看看这种方法行不行?先看一个例子voidmain(void){chars1[]=”abc”;chars2[]…

    2022年10月26日
  • idea for mac 2019版本 激活码破解方法

    idea for mac 2019版本 激活码破解方法,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • gcc rpm安装

    gcc rpm安装复制以下RPM包到某个目录compat-gcc-32-3.2.3-47.3.i386.rpmcompat-gcc-32-c++-3.2.3-47.3.i386.rpmcpp-3.4.6-3.i386.rpmgcc-3.4.6-3.i386.rpmgcc-c++-3.4.6-3.i386.rpmgcc-g77-3.4.6-3.i386.rpmgcc-gnat-3.4.6-…

  • 智能家居、智慧社区与智慧城市的关系_智能家居有哪些

    智能家居、智慧社区与智慧城市的关系_智能家居有哪些物联网技术可让智能家居应用变得更方便。过去几年年可说是智能家居生态链成形的关键年,许多科技大厂如Google并购Nest/Dropcam、三星并购SmartThings等,或是合作建立物联网联盟,如Qualcomm建立Allseen、Intel及三星主导OIC等,积极建立智能家居管理平台,提供有意进军智能家居的业者API,整合第三方软硬件资源,…

    2022年10月17日

发表回复

您的电子邮箱地址不会被公开。

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