Pyhton脚本编码总结1—脚本自身的编码问题和不同环境下print的使用小结

  • 格式:docx
  • 大小:74.51 KB
  • 文档页数:4

本测试涉及4个python脚本文件,文件命名规则为1(***)_###.py,
其中,
***表示python脚本本身的编码格式,
###表示python脚本第一行指定解释器以什么编码格式解释
Test1.1~Test1.3分别是在DOS、IDLE和Linux shell下运行4个python脚本文件
Tesit2.1~Test2.3与之相对应,唯一的区别是在中文字符串前加了个u
Test 1
****************
#coding=gbk
from struct import *
a = "好呀"
print a
print repr(a)
****************
Test 1.1: 执行环境:DOS
1(gbk)_gbk.py
1(gbk)_utf8.py
1(utf8)_gbk.py
1(utf8)_utf8.py
Test 1.2: 执行环境:IDLE
1(gbk)_gbk.py
1(gbk)_utf8.py
1(utf8)_gbk.py
1(utf8)_utf8.py
Test1.3: 执行环境:Linux shell
1(gbk)_gbk.py
1(gbk)_utf8.py
1(utf8)_gbk.py
1(utf8)_utf8.py
_______________________________________________________________ ___————————————————————————————————————————
Test 2
***************
#coding=gbk
from struct import *
a = u"好呀"
print a
print repr(a)
***************
Test 2.1 : 执行环境D0S
1(gbk)_gbk.py
1(gbk)_utf8.py
1(utf8)_gbk.py
1(utf8)_utf8.py
Test 2.2 : 执行环境IDLE
1(gbk)_gbk.py
1(gbk)_utf8.py
没反应…………
1(utf8)_gbk.py
1(utf8)_utf8.py
Test2.3: 执行环境Linux shell
1(gbk)_gbk.py
1(gbk)_utf8.py
1(utf8)_gbk.py
1(utf8)_utf8.py
对于上述测试结果的解释:
在python脚本中字符串默认的编码格式是与文本的编码格式一致的,即在gbk 编码的文本中,“好呀”的编码就是BAC3D1BD,而在utf-8编码的文本中,“好呀”
的编码就是E5A5BDE59180。

代表字符串的编码在整个执行过程中不会改变,所以当以print输出时,由于DOS环境的默认编码是GBK,所以会有Test1.1的结果。

注:(1(utf8)_gbk.py会报错是因为在PEP0263中有定义:
If a source file uses both the UTF-8 BOM mark signature and a magic encoding comment, the only allowed encoding for the commentis 'utf-8'. Any other encoding will cause an error.
如果将utf8文本的BOM去掉,那么在DOS中就不会报错了,而是现实与
1(utf8)_gbk相同的东西。

但是,如果在脚本文件中的中文字符串前加上u,那么python就会根据第一行的encoding指定的编码来将中文字符串的编码(在gbk文本中是BAC3D1BD,在utf-8文本中是E5A5BDE59180)转换成unicode,所以会出现Test2中
1(gbk)_utf8.py的错误,而在以print输出时,python会将内部unicode编码转换成环境默认编码,在这种情况下显示情况已经与最初的文本编码已经无关,所以即使Linux shell的默认编码是UTF-8也能正常显示了。

以上的解释可以帮我们形象地理解这一个过程,但实际上这个过程要更复杂!!!根据PEP0263的解释,Python的compiler/tokenizer的工作其实是分为5步的:
1. read the file
2. decode it into Unicode assuming a fixed per-file encoding
3. convert it into a UTF-8 byte string
4. tokenize the UTF-8 content
5. compile it, creating Unicode objects from the given Unicode data and creating string objects from the Unicode literal data by first reencoding the UTF-8 data into 8-bit string data using the given file encoding
对于前面没有加u的string objects来说,绕了一个大圈,先解码后编码,等于没变,所以才有解释中的“代表字符串的编码在整个执行过程中不会改变”,而一旦在字符串前面加上u,该字符串就不再是string类型,而是unicode类型(Unicode data),在第5步中会被编程Unicode objects来作为print的参数。

PS:print 可以接受两种类型的参数,一种是str,一种是unicode,如果是str类型的参数,那么对于输出环境来说只是一个字节串,怎么打印就看环境怎么解释了;而对于unicode类型的参数,那就直接根据环境来将unicode类型的参数转成可以正常打印的编码。