加入收藏 | 设为首页 | 会员中心 | 我要投稿 财气旺网 - 财气网 (https://www.caiqiwang.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

变量与字 符编码

发布时间:2022-12-07 11:28:22 所属栏目:Linux 来源:
导读:  >>> name1 = 'tom'//定义一个变量名为name1,其值为tom

  >>> name2 = 'jerry'//定义一个变量名为name2,其值为jerry

  >>> print(name1)//打印name1的值

  tom

  >>>
  >>> name1 = 'tom'//定义一个变量名为name1,其值为tom
 
  >>> name2 = 'jerry'//定义一个变量名为name2,其值为jerry
 
  >>> print(name1)//打印name1的值
 
  tom
 
  >>> print(name2)//打印name2的值
 
  jerry
 
  >>> id(name1)//查看name1变量在内存中的存储位置4365368712
 
  >>> id(name2)//查看name2变量在内存中的存储位置4365368824
 
  linux编码_linux查看文件编码_linux h264硬编码
 
  >>> name2 = 'tom'//name2变量重新赋值
 
  >>> print(name2)//打印name2的值
 
  tom
 
  >>> id(name2)//查看name2变量在内存中的存储位置4365368712
 
  linux查看文件编码_linux h264硬编码_linux编码
 
  1.4 内存回收机制
 
  当变量引用值为0时Python会自动进行内存回收
 
  如何使变量引用值变为0?
 
  //重新赋值使引用
 
  >>> a = 10
 
  >>> b = 20
 
  >>> id(a)9463072//a变量对应的数据的内存地址
 
  >>> id(b)9463392//b变量对应的数据的内存地址
 
  >>> b = a //将b变量的内存地址指针指向a变量数据的内存指针
 
  >>> id(b)9463072//b变量对应的数据的内存地址已发生改变,原有的内存指针将被Python自动回收
 
  //del删除变量
 
  >>> a = 10
 
  >>> id(a)9463072
 
  >>> del a //将a变量的内存指针销毁
 
  >>> id(a)
 
  Traceback (most recent call last):
 
  File "", line 1, in
 
  NameError: name 'a' is not defined
 
  2 字符编码2.1 字符编码的来龙去脉
 
  字符编码的作用:
 
  python解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascii)
 
  ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 = 256-1,所以,ASCII码最多只能表示 255 个符号。
 
  linux编码_linux h264硬编码_linux查看文件编码
 
  关于中文
 
  为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。
 
  GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。
 
  GB2312 支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的 GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。
 
  从ASCII、GB2312、GBK 到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。
 
  有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。
 
  显然ASCII码无法将世界上的各种文字和符号全部表示linux编码,所以,就需要新出一种可以代表所有字符和符号的编码,即:Unicode
 
  Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,规定所有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536,
 
  注:此处说的的是最少2个字节,可能更多
 
  UTF-8,是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类:ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存...
 
  UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1-6个字节表示一个符号,根据不同的符号而变化字节长度。
 
  UTF-8的编码规则很简单,只有二条:
 
  1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
 
  2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
 
  如表:
 
  1字节 0xxxxxxx
 
  2字节 110xxxxx 10xxxxxx
 
  3字节 1110xxxx 10xxxxxx 10xxxxxx
 
  4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 
  5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 
  6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 
  因此UTF-8中可以用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去那些控制位(每字节开头的10等),这些x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。
 
  实际将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数。
 
  因此那些基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一个字节的UTF-8编码(7个二进制位)便可以表示。
 
  所以,python解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascii),如果是如下代码的话:
 
  报错:ascii码无法表示中文
 
  #!/usr/bin/env python2.7
 
  print "你好,世界."# SyntaxError: Non-ASCII character '\xe4' in file ./test.py \
 
  # on line 3,but no encoding declared;
 
  改正:应该显式的告诉python解释器,用什么编码来执行源代码,即:
 
  #!/usr/bin/env python2.7# encoding: utf-8
 
  print "你好,世界."
 
  2.2 编码与解码
 
  Python提供了ord()和chr()函数,可以把字母和对应的数字相互转换
 
  >>> ord('A')65>>> chr(65)'A'
 
  utf8是如何节约硬盘和流量的
 
  s = "I'm 忘情"
 
  你看到的unicode字符集是这样的编码表:
 
  >>> ord('I')73>>> ord("'")39>>> ord('m')109>>> ord(u'忘')24536>>> ord(u'情')24773
 
  每一个字符对应一个十进制数字。
 
  因为计算机只懂二进制,因此,严格按照unicode的方式(UCS-2),应该这样存储
 
  I0000 0000 0100 1001'0000 0000 0010 0111
 
  m0000 0000 0110 1101
 
  忘0101 1111 1101 1000
 
  情0110 0000 1100 0101
 
  这个字符串总共占用了12个字节(3个欧洲字符,2个亚洲),但是对比中英文的二进制码,可以发现,英文前9位都是0!浪费啊,浪费硬盘,浪费流量。怎么办?UTF8:
 
  I0100 1001'0010 0111
 
  m0110 1101
 
  忘1110 0101 1011 1111 1001 1000
 
  情1110 0110 1000 0011 1000 0101
 
  utf8用了9个字节,对比unicode,少了三个,因为我们的程序英文会远多于中文,所以空间会提高很多!
 
  记住:一切都是为了节省你的硬盘和流量。
 
  2.2.1 py2的字符编码
 
  在py2中,有两种字符串类型:str类型和unicode类型;注意,这仅仅是两个名字,python定义的两个名字,关键是这两种数据类型在程序运行时存在内存地址的是什么?
 
  我们来看一下:
 
  # coding:utf8
 
  s1 = '情'
 
  print type(s1) # print repr(s1) # '\xe6\x83\x85'
 
  s2 = u'情'print type(s2) # print repr(s2) # u'\u60c5'
 
  内置函数repr可以帮我们在这里显示存储内容。原来,str和unicode分别存的是字节数据和unicode数据;那么两种数据之间是什么关系呢?如何转换呢?这里就涉及到编码(encode)和解码(decode)了
 
  # coding: utf8
 
  s1=u'忘'print repr(s1) # u'\u5fd8'
 
  b=s1.encode('utf8')print bprint type(b) # print repr(b) # '\xe5\xbf\x98'
 
  s2='忘情'
 
  u=s2.decode('utf8')print u# 忘情print type(u) # print repr(u) # u'\u5fd8\u60c5'
 
  #注意
 
  u2=s2.decode('gbk')print u2 # 蹇樻儏
 
  print len('忘情') # 6
 
  无论是utf8还是gbk都只是一种编码规则,一种把unicode数据编码成字节数据的规则,所以utf8编码的字节一定要用utf8的规则解码,否则就会出现乱码或者报错的情况。
 
  linux编码_linux查看文件编码_linux h264硬编码
 
  python2编码的特色:
 
  # coding:utf8
 
  print '忘情' # 忘情print repr('忘情') # '\xe5\xbf\x98\xe6\x83\x85'
 
  print (u"hello" + "wangqing") # hellowangqing
 
  print (u'忘情'+'至圣') # UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8
 
  # in position 0: ordinal not in range(128)
 
  Python 2 悄悄掩盖掉了 bytes 到 unicode 的转换,只要数据全部是 ASCII 的话,所有的转换都是正确的,一旦一个非 ASCII 字符偷偷进入你的程序,那么默认的解码将会失效,从而造成 UnicodeDecodeError 的错误。py2编码让程序在处理 ASCII 的时候更加简单。你付出的代价就是在处理非 ASCII 的时候将会失败。
 
  2.2.2 py3的字符编码
 
  python3 renamed the unicode type to str ,the old str type has been replaced by bytes.
 
  py3也有两种数据类型:str和bytes; str类型存unicode数据,bytes类型存bytes数据,与py2比只是换了一下名字而已。
 
  import json
 
  s='忘情'print(type(s))# print(json.dumps(s)) # "\u5fd8\u60c5"
 
  b=s.encode('utf8')print(type(b))# print(b)# b'\xe5\xbf\x98\xe6\x83\x85'
 
  u=b.decode('utf8')print(type(u))# print(u)# 忘情print(json.dumps(u)) # "\u5fd8\u60c5"
 
  print(len('忘情')) # 2
 
  linux h264硬编码_linux查看文件编码_linux编码
 
  python3的编码哲学:
 
  Python3最重要的新特性大概要算是对文本和二进制数据做了更为清晰的区分,不会对bytes字节串进行自动解码。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python3不会以任意隐式的方式混用str和bytes,正是这使得两者的区分特别清晰。你不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然)。
 
  #print('hello'+u'wangqing')# 字节串和unicode连接 py2:hellowangqingprint(b'hello'+'wangqing')# 字节串和unicode连接 py3:报错 can't concat bytes to str
 
  注意:无论py2,还是py3,与明文直接对应的就是unicode数据,打印unicode数据就会显示相应的明文(包括英文和中文)
 
  2.3 文件从磁盘到内存的编码
 
  说到这,才来到我们的重点!
 
  抛开执行程序,请问大家,文本编辑器大家都是用过吧,如果不懂是什么,那么word总用过吧,ok,当我们在word上编辑文字的时候,不管是中文还是英文,计算机都是不认识的,那么在保存之前数据是通过什么形式存在内存的呢?yes,就是unicode数据,为什么要存unicode数据,这是因为它的名字最屌:万国码!解释起来就是无论英文,中文,日文,拉丁文,世界上的任何字符它都有唯一编码对应,所以兼容性是最好的。
 
  好,那当我们保存了存到磁盘上的数据又是什么呢?
 
  答案是通过某种编码方式编码的bytes字节串。比如utf8,一种可变长编码,很好的节省了空间;当然还有历史产物的gbk编码等等。于是,在我们的文本编辑器软件都有默认的保存文件的编码方式,比如utf8,比如gbk。当我们点击保存的时候,这些编辑软件已经"默默地"帮我们做了编码工作。
 
  那当我们再打开这个文件时,软件又默默地给我们做了解码的工作,将数据再解码成unicode,然后就可以呈现明文给用户了!所以,unicode是离用户更近的数据,bytes是离计算机更近的数据。
 
  说了这么多,和我们程序执行有什么关系呢?
 
  先明确一个概念:py解释器本身就是一个软件,一个类似于文本编辑器一样的软件!
 
  现在让我们一起还原一个py文件从创建到执行的编码过程:
 
  打开pycharm,创建hello.py文件,写入
 
  ret=1+1
 
  s='忘情'print(s)
 
  当我们保存的的时候,hello.py文件就以pycharm默认的编码方式保存到了磁盘;关闭文件后再打开,pycharm就再以默认的编码方式对该文件打开后读到的内容进行解码,转成unicode到内存我们就看到了我们的明文;
 
  而如果我们点击运行按钮或者在命令行运行该文件时,python解释器这个软件就会被调用,打开文件,然后解码存在磁盘上的bytes数据成unicode数据,这个过程和编辑器是一样的,不同的是解释器会再将这些unicode数据翻译成C代码再转成二进制的数据流,最后通过控制操作系统调用cpu来执行这些二进制数据,整个过程才算结束。
 

(编辑:财气旺网 - 财气网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!