zoukankan      html  css  js  c++  java
  • 字符编码

                        字符编码

    1.    字符编码简介:

      1.1. ASCII    1.2. MBCS   1.3. Unicode主要研究

    2. Python2.x中的编码问题:

       2.1. str和unicode:

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

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

    再来看看encode()和decode()两个basestring的实例方法,理解了str和unicode的区别后,这两个方法就不会再混淆了:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    # coding: UTF-8

    u = u'汉'

    print repr(u) # u'u6c49'

    s = u.encode('UTF-8')

    print repr(s) # 'xe6xb1x89'

    u2 = s.decode('UTF-8')

    print repr(u2) # u'u6c49'

    # 对unicode进行解码是错误的

    # s2 = u.decode('UTF-8')

    # 同样,对str进行编码也是错误的

    # u2 = s.encode('UTF-8')

    需要注意的是,虽然对str调用encode()方法是错误的,但实际上Python不会抛出异常,而是返回另外一个相同内容但不同id的str;对unicode调用decode()方法也是这样。很不理解为什么不把encode()和decode()分别放在unicode和str中而是都放在basestring中,但既然已经这样了,我们就小心避免犯错吧

    2.2. 字符编码声明

         源代码文件中,如果有用到非ASCII字符,则需要在文件头部进行字符编码的声明,如下:

    1

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

    实际上Python只检查#、coding和编码字符串,其他的字符都是为了美观加上的。另外,Python中可用的字符编码有很多,并且还有许多别名,还不区分大小写,比如UTF-8可以写成u8。参见http://docs.python.org/library/codecs.html#standard-encodings。

    另外需要注意的是声明的编码必须与文件实际保存时用的编码一致,否则很大几率会出现代码解析异常。现在的IDE一般会自动处理这种情况,改变声明后同时换成声明的编码保存,但文本编辑器控们需要小心 :)

    2.3. 读写文件

      

    内置的open()方法打开文件时,read()读取的是str,读取后需要使用正确的编码格式进行decode()。write()写入时,如果参数是unicode,则需要使用你希望写入的编码进行encode(),如果是其他编码格式的str,则需要先用该str的编码进行decode(),转成unicode后再使用写入的编码进行encode()。如果直接将unicode作为参数传入write()方法,Python将先使用源代码文件声明的字符编码进行编码然后写入。

    coding: UTF-8
     
    f = open('test.txt')
    s = f.read()
    f.close()
    print type(s) # <type 'str'>
    # 已知是GBK编码,解码成unicode
    u = s.decode('GBK')
     
    f = open('test.txt', 'w')
    # 编码成UTF-8编码的str
    s = u.encode('UTF-8')
    f.write(s)
    f.close()
    

    3.一些建议

    3.1. 使用字符编码声明,并且同一工程中的所有源代码文件使用相同的字符编码声明

        3.2. 抛弃str,全部使用unicode

         3.3. 使用codecs.open()替代内置的open()。

       3.4. 绝对需要避免使用的字符编码:MBCS/DBCS和UTF-16
    4.python2与python3的区别
      4.1str类型

    当python解释器执行到产生字符串的代码时(例如s='林'),会申请新的内存地址,然后将'林'encode成文件开头指定的编码格式,这已经是encode之后的结果了,所以s只能decode

    1 #_*_coding:gbk_*_
    2 #!/usr/bin/env python
    3 
    4 x='林'
    5 # print x.encode('gbk') #报错
    6 print x.decode('gbk') #结果:林

    所以很重要的一点是:

    在python2中,str就是编码后的结果bytes,str=bytes,所以在python2中,unicode字符编码的结果是str/bytes

        #coding:utf-8
        s='林' #在执行时,'林'会被以conding:utf-8的形式保存到新的内存空间中

        print repr(s) #'xe6x9ex97' 三个Bytes,证明确实是utf-8
        print type(s) #<type 'str'>
        s.decode('utf-8') # s.encode('utf-8') #报错,s为编码后的结果bytes,所以只能decode

     unicode类型

       当python解释器执行到产生字符串的代码时(例如s=u'林'),会申请新的内存地址,然后将'林'以unicode的格式存放到新的内存空间中,所以s只能encode,不能decode

    复制代码
    s=u'林'
    print repr(s) #u'u6797'
    print type(s) #<type 'unicode'>
    
    
    # s.decode('utf-8') #报错,s为unicode,所以只能encode
    s.encode('utf-8') 
     4.3 python3也有两种字符串类型str和bytes
     str是unicode
    复制代码
    #coding:utf-8
    s='林' #当程序执行时,无需加u,'林'也会被以unicode形式保存新的内存空间中,
    
    #s可以直接encode成任意编码格式
    s.encode('utf-8')
    s.encode('gbk')
    
    print(type(s)) #<class 'str'>
    复制代码
                                                 
     

    bytes是bytes

    复制代码
    #coding:utf-8
    s='林' #当程序执行时,无需加u,'林'也会被以unicode形式保存新的内存空间中,
    
    #s可以直接encode成任意编码格式
    s1=s.encode('utf-8')
    s2=s.encode('gbk')
    
    
    
    print(s) #林
    print(s1) #b'xe6x9ex97' 在python3中,是什么就打印什么
    print(s2) #b'xc1xd6' 同上
    
    print(type(s)) #<class 'str'>
    print(type(s1)) #<class 'bytes'>
    print(type(s2)) #<class 'bytes'
     
     
     end
     
     
     
     
     
     
     
                   
     
  • 相关阅读:
    《Linux内核设计与实现》读书笔记(二)- 内核开发的准备
    《Linux内核设计与实现》读书笔记(一)-内核简介
    Redis常用命令
    redis——学习之路五(简单的C#使用redis)
    Redis——学习之路四(初识主从配置)
    Redis——学习之路三(初识redis config配置)
    Redis——学习之路二(初识redis服务器命令)
    Redis——学习之路一(初识redis)
    SQL Server 查询分析器提供的所有快捷方式(快捷键)
    降维中的特征选择(转)
  • 原文地址:https://www.cnblogs.com/hanxiaofeicf/p/7027254.html
Copyright © 2011-2022 走看看