解释器和文件

python文件编码

查看文件自身编码

➜  encoding file file_encoding.py 
file_encoding.py: UTF-8 Unicode text

文件本身的编码是UTF-8

不声明文件编码

➜  encoding cat file_encoding.py 
print '你好'
print u'你好'
➜  encoding python file_encoding.py 
  File "file_encoding.py", line 1
SyntaxError: Non-ASCII character '\xe4' in file file_encoding.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

默认解释器按照ASCII编码来解码你好对应的UTF-8编码后字节串,所以报错了

声明文件编码为utf-8

➜  encoding cat file_encoding.py   
# encoding: utf-8
print '你好'
print u'你好'
➜  encoding python file_encoding.py
你好
你好

# encoding: utf-8告诉解释器使用UTF-8来解码你好对应的UTF-8编码后字节串

文件编码声明不在第一行

➜  encoding cat file_encoding.py   
# author zhujipeng

# encoding: utf-8
print '你好'
print u'你好'
➜  encoding python file_encoding.py
  File "file_encoding.py", line 4
SyntaxError: Non-ASCII character '\xe4' in file file_encoding.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

解释器会读取文件的第一行来确定解析python使用的编码,所以编码声明要放在第一行

vim修改文件编码声明

vim不会修改文件本身的编码

➜  encoding file file_encoding.py 
file_encoding.py: UTF-8 Unicode text
➜  encoding cat file_encoding.py 
# encoding: gbk
print '你好'
print u'你好'
➜  encoding python file_encoding.py 
你好
浣犲ソ

字符串你好在文件被解析时按照gbk进行了解码, print输出时由按照utf-8进行了编码

模拟输入输出过程

保存

保存过程会将你输入的字符根据文件的编码转化为字节进行保存

>>> '你好'.encode('utf-8')
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> u'你好'.encode('utf-8')
'\xe4\xbd\xa0\xe5\xa5\xbd'

字符串和字节串你好在编码为utf-8的文件中保存时是6个字节,一个中文在utf-8中用3个字节表示

解析

解析过程会根据你声明的文件编码将字节转化为内部编码unicode形式的字符存储在内存中

严格来说unicode是字符集,UTF-16UCS-2才是编码, 内存的地址也是以字节为单位的,所以其实内存中的字符也是按字节存储的 只是解析器(或者编译器)在处理时会以两个字节为单位进行处理,这个过程是透明的

>>> u'你好'.encode('utf-8').decode('gbk')
u'\u6d63\u72b2\u30bd'

字符串你好在文件被解析时按照gbk解码为了3个字符,一个中文在gbk中用2个字节表示

输出
>>> '你好'.encode('utf-8').decode('gbk').encode('utf-8')
'\xe6\xb5\xa3\xe7\x8a\xb2\xe3\x82\xbd'

字符串你好在输出到终端时会根据终端的编码utf-8进行编码,转换成了9个字节

显示
>>> print u'你好'.encode('utf-8').decode('gbk')
浣犲ソ

显示程序会将输出的9个字节按照终端的编码utf-8进行编码,转换成了3个字符

乱码

由于字符串整个编码解码的过程中使用编码不一致,所以乱码了 而字节串存储和展示的编码一致,所以没有乱码

pycharm修改文件编码声明

pycharm会修改文件本身的编码

➜  encoding file file_encoding.py 
file_encoding.py: ISO-8859 text
➜  encoding cat file_encoding.py 
# encoding: gbk
print '���'
print u'���'
➜  encoding python file_encoding.py 
���
你好

字节串和字符串你好cat输出时保持字节流不变, 进行展示时则被按照utf-8编码进行了解码

模拟输入输出过程

保存

保存过程会将你输入的字符根据文件的编码转化为字节进行保存

>>> '你好'.encode('gbk')
'\xc4\xe3\xba\xc3'
>>> u'你好'.encode('gbk')
'\xc4\xe3\xba\xc3'

字符串和字节串你好在编码为gbk的文件中保存时是4个字节,一个中文在gbk中用2个字节表示

解析

解析过程会根据你声明的文件编码将字节转化为内部编码unicode形式的字符存储在内存中

严格来说unicode是字符集,UTF-16UCS-2才是编码, 内存的地址也是以字节为单位的,所以其实内存中的字符也是按字节存储的 只是解析器(或者编译器)在处理时会以两个字节为单位进行处理,这个过程是透明的

>>> u'你好'.encode('gbk').decode('gbk')
u'\u4f60\u597d'

字符串你好在文件被解析时按照gbk解码为了2个字符,一个中文在gbk中用2个字节表示

输出
>>> u'你好'.encode('gbk').decode('gbk') .encode('utf-8')
'\xe4\xbd\xa0\xe5\xa5\xbd'

字符串你好在输出到终端时会根据终端的编码utf-8进行编码,转换成了6个字节

显示
>>> print u'你好'.encode('gbk').decode('gbk') .encode('utf-8')
你好

显示程序会将输出的6个字节按照终端的编码utf-8进行编码,转换成了2个字符

乱码

由于字符串整个编码解码的过程中使用的编码一致,所以没有乱码 而字节串存储和展示的编码不一致,所以乱码了

python文件读写

默认的文件写入

➜  encoding cat file_encoding.py   
# encoding: utf-8
with open("test_file.txt", "wa") as f:
    f.write("中")
    f.write(u"中")
➜  encoding python file_encoding.py
Traceback (most recent call last):
  File "file_encoding.py", line 4, in <module>
    f.write(u"中")
UnicodeEncodeError: 'ascii' codec can't encode character u'\u4e2d' in position 0: ordinal not in range(128)

由于python无法知道文件的编码,所以会使用默认编码ascii来对字符串进行编码

改变的文件写入

➜  encoding cat file_encoding.py 
# encoding: utf-8

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

with open("test_file.txt", "wa") as f:
    f.write("中")
    f.write(u"中")
➜  encoding python file_encoding.py 
encoding cat test_file.txt 
中中

设置默认编码为utf-8就可以正常写入了

默认的文件读取

➜  encoding cat file_encoding.py   
# encoding: utf-8

for line in open("test_file.txt", "r"):
    print type(line), line

➜  encoding python file_encoding.py
<type 'str'> 中中

读取文件时返回的类型为字节串

Copyright © zhujipeng 2017 all right reserved,powered by Gitbook 该文件修订时间: 2017-12-16 15:12:10

results matching ""

    No results matching ""