天天看点

python 编码乱码问题(decode,encode)

  • ANSI:

    ANSI字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个\0结尾,常用于txt文本文件

  • Unicode:
    • Unicode字符串每个字符(汉字、英文字母)都占2个字节,以2个连续的\0结尾;
    • NT操作系统内核用的是这种字符串,常被定义为typedef unsigned short wchar_t;所以我们有时常会见到什么char无法转换为unsigned short之类的错误,其实就是unicode。
    • little endian: 最低位地址存放低位字节,可称低位优先,内存从最低地址开始按顺序存放(低数位数字先写)。最低位字节放最前面。
    • big endian: 最低位地址存放高位字节,可称高位优先,内存从最低地址开始按顺序存放(高数位数字先写)。最高位字节放最前面。
  • UTF8:

    UTF8是Unicode一种压缩形式。

    • 英文A在unicode中表示为0x0041,老外觉得这种存储方式太浪费,

      因为浪费了50%的空间,于是就把英文压缩成1个字节,成了utf8编码,但是汉字在utf8中占3个字节,

      显然用做中文不如ANSI合算,这就是中国的网页用作ANSI编码而老外的网页常用utf8的原因。

  • 签名BOM:

    BOM 是 Byte Order Mark 的缩写(字节顺序标记),是编码方案里用于标识编码的标准标记。

    • ANSI 文件没有 BOM
    • UTF-8 文件的 BOM 为:EF BB BF,不过 UTF-8 文件可以有 BOM,也可以没有 BOM
    • Unicode big endian 文件的 BOM 为:FE FF
    • Unicode little endian 文件的 BOM 为:FF FE

以上是各编码常识。

错误代码:

UnicodeEncodeError: 'ascii' codec can't encode characters in position -: ordinal not in range()
           

字符串在python内部的表示是unicode编码,因此,在做编码转换时,通常需要unicode作为中间编码,即先将其他编码的字符串解码(decode) 成unicode,再从unicode 编码(encode) 成另一种编码。

- decode: 将其他编码的字符串转换成unicode编码,如str1.decode(‘gb2312’),表示将gb2312编码的字符串str1转成unicode编码。

- encode: 将unicode编码转换成其他编码的字符串,如str2.encode(‘gb2312’),表示将unicode编码的字符串str2转成gb2312编码。

因此 :转码的时候一定要先搞明白,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码

  • 如:s=’中文’

    如果是在utf8的文件中,该字符串就是utf8编码,如果是在gb2312的文件中,则其编码为gb2312。这种情况下,要进行编码转换,都需 要先用decode方法将其转换成unicode编码,再使用encode方法将其转换成其他编码。通常,在没有指定特定的编码方式时,都是使用的系统默 认编码创建的代码文件。

  • 如:s=u’中文’

    则该字符串的编码就被指定为unicode了,即python的内部编码,而与代码文件本身的编码无关。因此,对于这种情况做编码转换,只需要直接使用encode方法将其转换成指定编码即可。

以下,关于python 相关编码代码解释:

当你在py文件的第一行中,写了这句话,并确实按照这个编码保存了文本的话,那么这句话有以下几个功能。

1. 使得词法分析器能正常运作,对于注释中的中文不报错了。

2. 对于u”中文”这样literal string能知道两个引号中的内容是utf8编码的,然后能正确转换成unicode

3. “中文”对于这样的literal string你会知道,这中间的内容是utf8编码,然后就可以正确转换成其它编码或unicode了。

sys.getfilesystemencoding()
           

返回的字符编码用于将Unicode文件名映射到底层操作系统使用的文件名。

对于Windows返回’mbcs’, 或对于Macintosh OSX返回’utf-8’。在UNIX系统上,编码取决于区域设置并将返回区域参数CODESET的值。在使用默认编码的系统上可能返回None。

-未完待续。。。