系统编码,可以通过locale命令查看(LINUX)https://wiki.archlinux.org/index.php/Locale_(简体中文), centos7 配置文件在/etc/profile.d/lang.sh

文件编码,它代表源码文件内的所有内容都是根据词方式编码成二进制码流,存入到磁盘中的。

python编码,是指python内设置的解码方式。如果不设定的话,python2默认是ascii解码。在源码文件开头(一定是第一行):#-*-coding:UTF-8-*-,源码文件的设置解码方式是UTF-8

unicode是python中的字符集,utf-8是unicode的一种实现,所以python2中有string和unicode两种字符串,string就是按照python编码的,unicode是字符集,有人称unicode为内码。http://blog.sina.com.cn/s/blog_67852f560101fjtc.html

Python内部的字符串一般都是 Unicode编码。代码中字符串的默认编码与代码文件本身的编码是一致的。所以要做一些编码转换通常是要以Unicode作为中间编码进行转换的,即先将其他编码的字符串解码(decode)成 Unicode,再从 Unicode编码(encode)成另一种编码。
        decode 的作用是将其他编码的字符串转换成 Unicode 编码,eg name.decode(“GB2312”),表示将GB2312编码的字符串name转换成Unicode编码
        encode 的作用是将Unicode编码转换成其他编码的字符串,eg name.encode(”GB2312“),表示将GB2312编码的字符串name转换成GB2312编码

 

所以在用python读写文件的时候,要注意文件编码是哪种,自己python解释器用哪种编码方式。

系统编码:locale:gbk
python源文件test.py
#coding='UTF-8'
s='文斌'
print s

在test.py保存的时候,会按照系统编码方式GBK的方式(有的编辑器也能自定义编码格式),编码成gbk二进制码流,存储到磁盘上。当运行该程序时。gbk二进制码流调入内存,并按照python设置的解码方式解码,也就是按照UTF-8的方式解码,所以结果不是错误提示,就是显示出来的是乱码。

 

再比如最常看到的:

test1.py

s = '文斌'
print s.decode()

 

没有指定python编码方式,默认肯定为ascii,所以就没办法编码文字  '文斌'  了,所以运行这个脚本肯定报错,当你用  # -*- coding: utf-8 -*-  头文件后就指定了python解析器的编码方式,就不会报错了。
===================================================================================

下面是一下大神的总结

编码:
http://www.crifan.com/files/doc/docbook/char_encoding/release/html/char_encoding.html
计算机中存放的都是0和1的二进制值。8个位对应一个字节,常用16进制来表示,注意是表示,因为是2^4,所以0xF就表示这个字节,0x是16进制的意思,0xF就表示了这个字节里是11111111

ASCII的编码规则,由于最初只是为英文字母所考虑的,而英文只有26个字母,以及加上其他大小写字母,常见的字符,常见数字等,所有的加起来,也就几十个,而一个字节8位中前7位的理论上可以表示27=128个字符,所以对于设计出来的编码规则来说,只需要用一个字节来表示,就足够了。


Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

UTF-8是Unicode的实现方式之一。

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

Unicode符号范围(十六进制)  UTF-8编码方式(二进制)
0000 0000-0000 007F       0xxxxxxx
0000 0080-0000 07FF       110xxxxx 10xxxxxx
0000 0800-0000 FFFF       1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx


python 头文件:
http://www.crifan.com/python_head_meaning_for_usr_bin_python_coding_utf-8/

1
# -*- coding: utf-8 -*-
对此格式的详细解释是:
    1    如果没有此文件编码类型的声明,则python默认以ASCII编码去处理,如果你没声明编码,但是文件中又包含非ASCII编码的字符的话,python解析器去解析的python文件,自然就会报错了。
    2    必须放在python文件的第一行或第二行
    3    更加精确的解释是: "coding[:=]\s*([-\w.]+)"
   
    4    为了照顾特殊的Windows中的带BOM(’\xef\xbb\xbf’)的UTF-8:
             如果你的python文件本身编码是带BOM的UTF-8,即文件前三个字节是:’\xef\xbb\xbf’,那么:
             i    即使你没有声明文件编码,也自动当做是UTF-8的编码
             ii    如果你声明了文件编码,则必须是声明了(和你文件编码本身相一致的)UTF-8
             否则(由于声明的编码和实际编码不一致,自然)会报错



python编码
http://blog.chinaunix.net/uid-27838438-id-4227131.html

Python内部的字符串一般都是 Unicode编码。代码中字符串的默认编码与代码文件本身的编码是一致的。所以要做一些编码转换通常是要以Unicode作为中间编码进行转换的,即先将其他编码的字符串解码(decode)成 Unicode,再从 Unicode编码(encode)成另一种编码。
        decode 的作用是将其他编码的字符串转换成 Unicode 编码,eg name.decode(“GB2312”),表示将GB2312编码的字符串name转换成Unicode编码
        encode 的作用是将Unicode编码转换成其他编码的字符串,eg name.encode(”GB2312“),表示将GB2312编码的字符串name转换成GB2312编码

所以在进行编码转换的时候必须先知道 name 是那种编码,然后 decode 成 Unicode 编码,最后载 encode 成需要编码的编码。当然了,如果 name 已经就是 Unicode 编码了,那么就不需要进行 decode 进行解码转换了,直接用 encode 就可以编码成你所需要的编码。

例子:读取一个文件编码格式为gbk的文件,然后输出一个utf8格式的文件

        # coding: UTF-8
        
        fp1 = open('test.txt', 'r')
        info1 = fp1.read()
        # 已知是 GBK 编码,解码成 Unicode
        tmp = info1.decode('GBK')
        
        fp2 = open('test.txt', 'w')
        # 编码成 UTF-8 编码的 str
        info2 = tmp.encode('UTF-8')
        fp2.write(info2)
        fp2.close()
        

设置python编码方法:注意要先reload

import sys
reload(sys)
sys.setdefaultencoding("utf-8")
print sys.getdefaultencoding()






unicode是一个内置函数,第二个参数指示源字符串的编码格式。
s1 = u'中文'
s2 = unicode('中文','gbk')
s3 = s1.decode('gbk')


在vim中查看文件编码格式
:set fileencoding