• python中的编解码小结


    在用python27写文件或者上传文件时遇到这样一个问题:。在网上搜了下说加入以下三行代码可以解决:

    import sys 
    reload(sys) 
    sys.setdefaultencoding('utf-8')

    试了一下果然解决问题。

    总结一下原理:

    Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。编码是 unicode -> str,相反的,解码就是 str -> unicode。剩下的问题就是确定何时需要进行编码或者解码了.关于文件开头的"编码指示",也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用"编码指示"来修正. 关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。比如我有如下代码:

    #! /usr/bin/env python 
    # -*- coding: utf-8 -*- 
    s = '中文'  # 注意这里的 str 是 str 类型的,而不是 unicode 
    s.encode('gb18030')

    这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型的,因此 Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是 ANSCII,如果 s 不是这个类型就会出错。拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) 。
    对于这种情况,我们有两种方法来改正错误: 
    一是明确的指示出 s 的编码方式:

    #! /usr/bin/env python 
    # -*- coding: utf-8 -*- 
    
    s = '中文' 
    s.decode('utf-8').encode('gb18030')

    二是更改 sys.defaultencoding 为文件的编码方式

    #! /usr/bin/env python 
    # -*- coding: utf-8 -*- 
    
    import sys 
    reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入 
    sys.setdefaultencoding('utf-8') 
    
    str = '中文' 
    str.encode('gb18030')

    但是!用sys.setdefaultencoding('utf-8')这种方式有时候会遇到很奇怪的bug。问题不在描述了,都是血泪。

    所以再遇到UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-13: ordinal not in range(128)时,一律明确的指示出编码方式。

    比如在读写文件时,需要先将读出的文本decode成需要的文本,写文件时,需要encode成字节再写入。

    file_object = open(read_file, 'r')
    conf_object = open(write_file, 'w') 
    try:
        all_text = file_object.read()
        all_text = all_text.decode('utf-8')
        all_text = all_text.replace('aa', 'bb')
        all_text = all_text.encode('utf-8')
        conf_object.write(all_text)
    except:
        print "read or write failed"

    几个建议:

    • 当取回来的数据与你当前脚本中声明的编码不一致时就要做编码转换。
    • 所有 text string 都应该是 unicode 类型,而不是 str,如果你在操作 text,而类型却是 str,那就是在制造 bug。
    • 在需要转换的时候,显式转换。从字节解码成文本,用 var.decode(encoding),从文本编码成字节,用 var.encode(encoding)
    • 从外部读取数据时,默认它是字节,然后 decode 成需要的文本;同样的,当需要向外部发送文本时,encode 成字节再发送
  • 相关阅读:
    Export excel的终级解决方案
    Power Designer 常见问题
    正反向数据库及生成设计报告
    寻求最佳开发模式,免得落得“精”尽人亡
    XmlNode与XmlElement的区别总结
    软件版本的定义:
    我发现博客园一个很严重的问题
    sql 行转列的终极写法
    js 自定义 $ 选择器
    可持续集成环境相关文章
  • 原文地址:https://www.cnblogs.com/zoro-robin/p/6558628.html
Copyright © 2020-2023  润新知