5分钟理解python乱码

2020-07-24  本文已影响0人  黄多卜

python乱码的问题常见,只是临时解决而不系统理解的话,日后总会再找上来。

字符集编码简史

计算机是美帝发明的,最初只需要表示英文字母、标点符号,用单字节就够了,这时是ascii编码;后面其他国家用电脑表示不了自己的文字,又各自创建了各种编码,例如中文简体gbk;不同编码之间难沟通,有可能用中文Windows开发的软件在美国人电脑上就显示不了,所以最后发明了大一统的万国码,unicode。

unicode相当于英语,国际通用,用于国与国之间语言的转换交流。

编码种类

  • ASCII 占1个字节,只支持英文
  • GB2312 占2个字节,支持6700+汉字
  • GBK GB2312的升级版,支持21000+汉字
  • Shift-JIS 日本字符
  • ks_c_5601-1987 韩国编码
  • TIS-620 泰国编码
  • unicode 2-4字节 直接支持全球所有语言,已经收录136690个字符,并还在一直不断扩张中
  • UTF-8是什么

    使用unicode有时有点浪费空间。例如:利用unicode表示“Python”需要12个字节才能表示,比原来ASCII表示增加了1倍。

    字符串在表示层时不会特别大(图像、音频更大),可以使用unicode来处理,但是存储层和传输层一般数据都会非常多,继续用unicode则浪费空间。

    为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间。

  • UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
  • UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。
  • UTF-32: 使用4个字节表示所有字符;总结:UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。
  • 乱码的根本原因

    字符在不同的编码解码过程中,最终编码的格式与初始格式不同,就会乱码。不同操作系统、不同地区语言、不同阅读软件、不同编程语言的默认编码格式都不一定相同,要留意。

    python2中的字符体系

    python2发明的时候还没有unicode编码,也没想到会全球流行,它的默认编码是ascii的,要在第一行注释指定文件用utf-8编码才能使用中文。

    # coding: utf-8

    python2中有两种字符类型 str 和 unicode,可以用type(v)查看变量类型。

    >>> a='好'>>> type(a)<type 'str'>>>> a'\xe5\xa5\xbd' >>> b=u'好'>>> type(b)<type 'unicode'>>>> bu'\u597d'

    <type ‘unicode’>即是字符的unicode编码类型,<type ‘str’>则表示除unicode外的其他编码类型(UTF-8\GBK\Latin-1等)。

    str与unicode的转换

    decode时指定str原来的编码格式,encode指定要转换成的编码格式。

    所以生成一个unicode类型变量有两种方式,一个是定义时以u开头,一个是对str类型进行decode

    python3的改变

    python3中将默认编码改为unicode,其他不兼容的地方也多,要区分。

    简单用法

    以py2为例, 牢记一点“表示层用unicode,存储传输用utf-8”

  • 第一行指定源码文件的编码格式 #coding: utf-8
  • 重置进程的默认编码为utf-8
  • import sysreload(sys)sys.setdefaultencoding('utf-8')
  • 使用时将字符变量都decode为unicode
  • oriCodeFormat = 'utf-8' # or 'gbk' 'latin-1' ...newVar = var.decode(oriCodeFormat)doSth(newVar)

    参考

    Python 编码为什么那么蛋疼? - Alex-金角大王的回答 - 知乎
    Python 编码为什么那么蛋疼? - 刘志军的回答 - 知乎

    上一篇下一篇

    猜你喜欢

    热点阅读