zoukankan      html  css  js  c++  java
  • python里我最容易搞不清楚问题之一的encode和decode

    因为我自己整理在笔记本上好几次,但是今天看到的时候,又凌乱了。所以还是再次重新整理到博客上。

    在计算机的世界里:

    1 bytes(字节) == 8 bite(比特);每个bite里存放0或1。

    于是一个字节能表示的最大数是:11111111(2) == 255(10);能表示的最小数是:00000000(2) == 0(10)

    那么1个字节的范围是:[0, 2^8-1];

    同理2个字节的范围是:[0, 2^16-1];以此类推···

    电脑(是美国人发明的)最早使用的是ASCII编码准则,里面包含了127个字符,能够对应表示所有的大小写英文字母、数字、特殊符号。因为127<255,所以一个字节对于英文字符的处理是足够的。

    但是汉字有几万个,一个字节是完全不够的。至少需要两个字节(2^16-1),并且不与原来的ASCII编码冲突。所以中国制定了GB2312。

    中国对应的GB2312;韩国对应的Euc-kr;日本对应的Shift-JIS等等。各国不统一的标准后,就会造成冲突:乱码。

    于是统一的标准出现了:Unicode:把所有语言都统一到一套编码里。

    Unicode的标准是:通常2个字节表示一个字符,非常生僻字符用4个字节表示。

    Unicode解决了乱码冲突问题,同时带来了效率和内存问题:因为Unicode用2个字节表示一个字符,ASCII用1个字节表示。效率和存储上都是一倍的差距。

    于是UTF-8编码诞生了:英文字符用1个字节、中文字符用3个字节、生僻字符4至6个字节。如果文本中包含大量英文字符,UTF-8就更节省空间,传输效率也更快。

    (ASCII编码属于UTF-8的一部分,所以只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续使用)

    字符 ASCII Unicode UTF-8
    A 01000001 00000000 01000001 01000001
    x 01001110 00101101 11100100 10111000 10101101

    python里有2种字符串:

    字节码串:没有数据描述的数据

    字符串:原始数据+数据描述(指出何种字符集)

    python2里:

    1.str:字节码串

    2.unicode:字符串(定义时需要u''去声明)

    因此在python2里,日常字符串的表示为:u'xxx',当前编码设定下的字节码串的表示为:'xxx'。非常不方便,本末倒置。于是在python3里对其修改。

    python3里:

    1.bytes:字节码串

    2.str:字符串(默认支持Unicode字符集,所以不需要u''去定义字符串)

    所以在python3里,日常字符串的表示为:'xxx',字节码串的表示为:b'xxx'。

    所以现在一般认为python里有两种字符串:

    1.存储文本的str:Unicode存储;len(str)是计算字符数

    2.存储字节的bytes:原始字节序列ASCII存储;len(bytes)是计算字节数

    bytes --decode--> unicode --encode--> bytes

    encode()方法:

    >>> 'abc'.encode('ascii')  # 按照ascii编码将unicode字符串转换成bytes字节码串
    b'abc'
    >>> '中文'.encode('utf-8')  # 照ascii编码将unicode字符串转换成bytes字节码串
    b'xe4xb8xadxe6x96x87'
    >>> '中文'.encode('ascii')  # 因为ascii编码里没有中文字符,所以报错
    Traceback (most recent call last):
      File "<pyshell#11>", line 1, in <module>
        '中文'.encode('ascii')
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

    decode()方法:

    >>> b'abc'.decode('ascii')  # 按照ascii编码将bytes字节码串解码为str字符串
    'abc'
    >>> b'xe4xb8xadxe6x96x87'.decode('utf-8')  # 按照utf-8编码将bytes字节码串解码为str字符串
    '中文'
    >>> b'xe4xb8xadxff'.decode('utf-8')
    Traceback (most recent call last):
      File "<pyshell#15>", line 1, in <module>
        b'xe4xb8xadxff'.decode('utf-8')
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
    >>> b'xe4xb8xadxff'.decode('utf-8', errors='ignore')  # 设置错误处理方案为‘ignore’便可忽略xff的错误
    ''

    写完我自己清楚多啦~ 

  • 相关阅读:
    09-导入/导出
    django 登录
    python 数据结构
    Django 加密解密
    MySQL SQL语句
    libpython3.6m.so.1.0文件缺失
    环境变量配置
    Django 设置session过期时间
    Django 搜索功能
    表单校验
  • 原文地址:https://www.cnblogs.com/hongdanni/p/10484874.html
Copyright © 2011-2022 走看看