zoukankan      html  css  js  c++  java
  • python2 编码问题详解

    实例对比

    定义|type|str|unicode|print|encode('utf8')|decode('utf8')|encode('unicode-escape')|encode('string-escape')|编码推测
    ---|---|---|---|---|---|---|---|---|---|---
    a='中'|str|'x??x??'|报错|正常|报错|报错|报错|'\x??\x??'|ascii
    a=u'中'|unicode|报错|u'u????'|正常|'x??x??x??'|报错|'\u????'|报错|unicode

    ascii --> unicode --> utf-8

    • ascii:最早的,容量最小的编码方式。1个字节表示一个字符。
    • unicode:加入多国字符,一般是2个字节表示一个字符,偏僻字用4个字节。缺点:浪费存储空间。
    • utf-8:为了解决浪费空间的问题,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。

    在计算机内存中,统一使用Unicode编码。当需要保存到硬盘或者需要传输的时候,可以转换为UTF-8编码。

    1.Python的诞生比Unicode标准发布的时间还要早,所以最早的Python只支持ASCII编码

    查看默认编码

    >>> import sys
    >>> sys.getdefaultencoding()
    'ascii'
    

    Python内建的ord()和chr()函数,可以把字母和对应的数字相互转换:

    >>> ord('A')
    65
    >>> chr(65)
    'A'
    

    2.Python在后来添加了对Unicode的支持,以Unicode表示的字符串用u'...'表示

    >>> u'中'
    u'u4e2d'
    

    u后面是十六进制的Unicode码。

    3.unicode --> utf-8

    >>> u'ABC'.encode('utf-8')
    'ABC'
    >>> u'中文'.encode('utf-8')
    'xe4xb8xadxe6x96x87'
    

    英文字符转换后表示的UTF-8的值和Unicode值相等(但占用的存储空间变小,2个字节变为1个字节),而中文字符转换后1个Unicode字符转化为UTF-8字符后,两个字节变为3个字节。用len()函数显示,从1个字符长度变为3个字符。

    >>> len(u'中')
    1
    >>> len(u'中'.encode('utf-8'))
    3
    

    4.utf-8 --> unicode

    >>> 'abc'.decode('utf-8')
    u'abc'
    >>> test = 'xe4xb8xadxe6x96x87'.decode('utf-8')
    u'u4e2du6587'
    >>> print test
    中文
    

    5.str --> utf-8

    # UTF-8无法解码str
    >>> a.decode('utf8')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:Python2710libencodingsutf_8.py", line 16, in decode
        return codecs.utf_8_decode(input, errors, True)
    UnicodeDecodeError: 'utf8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
    
    # 而用GBK可以解码str
    >>> t = a.decode('gbk')
    >>> t
    u'u4e2d'
    >>> t.encode('utf8')
    'xe4xb8xad'
    

    >>> t = unicode(a, 'gbk')  # 估计调用了decode方法
    >>> t
    u'u4e2d'
    >>> t.encode('utf8')
    'xe4xb8xad'
    

    读取txt文件

    # coding: utf-8
    
    import os
    
    here = os.path.dirname(__file__)
    fpath = os.path.join(here, '1.txt')
    with open(fpath,'r') as f:
        print type(f)
        ls = f.xreadlines()
        print ls
        for l in ls:
            print l
            print type(l)
    

    结果(说明了读取文件时默认是str):

    <type 'file'>
    <open file 'C:\Users\weaming\Desktop\1.txt', mode 'r' at 0x05574078>
    abc
    
    <type 'str'>
    中国
    <type 'str'>
    

    写入文件

    with open(os.path.join(here, '2.txt'), 'w') as f:
        f.write(u'abc
    中文'.encode('utf8'))
    

    可正确写入,显示为正常的“中文”。other-->unicode-->UTF8

    如何保存 .py 源代码文件

    • 保存:Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。
    • 读取:当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头(第一行或第二行)写上这一行行# -*- coding: utf-8 -*-

    终极原则:decode early, unicode everywhere, encode finally

    在输入或者声明字符串的时候,尽早地使用decode方法将字符串转化成unicode编码格式;然后在程序内使用字符串的时候统一使用unicode格式进行处理,比如字符串拼接、字符串替换、获取字符串的长度等操作;最后,在输出字符串的时候(控制台/网页/文件),通过encode方法将字符串转化为你所想要的编码格式,比如utf-8等。

    参考链接

  • 相关阅读:
    Educational Codeforces Round 20 D. Magazine Ad
    Educational Codeforces Round 20 C. Maximal GCD
    紫书第三章训练2 暴力集
    Educational Codeforces Round 20 B. Distances to Zero
    Educational Codeforces Round 20 A. Maximal Binary Matrix
    紫书第三章训练1 D
    紫书第一章训练1 D -Message Decoding
    HAZU校赛 Problem K: Deadline
    Mutual Training for Wannafly Union #8 D
    紫书第三章训练1 E
  • 原文地址:https://www.cnblogs.com/weaming/p/4956181.html
Copyright © 2011-2022 走看看