-
问题时间:
这是在我学习《Python3基础教程》用CGI创建动态网页时遇到的问题。
-
问题描述:
我在windows10,python3.5环境下用工具http.server实现CGI执行如下代码:
5+ 简单的CGI脚本
#!D:/Python/Python35/python.exe
print('Content-type: text/plain')
print()# 打印一个空行,以结束首部
print('Hello, world!')
尝试了:1. 建立cgi-bin目录并在目录下建py文件;2. 以及方法直接新建.cgi类型文件的方法;
1. 结果是直接将.py全部显示给我,2. 结果是直接给出一个.cgi类型文件点上去只能下载。
直接懵逼的我选择去找其他的实例:
最后发现的结果是:我的文件创建方式有问题以及文件.py文件的运行方式有问题。
-
问题原因:
文件创建方式问题:
可能是书上的源码太简单了,所以并没有报错,只是显示结果,然而我用了另一段比较完整的代码,命令行上就给我报错了:
line 1\r\nSyntaxError: Non-UTF-8 code starting with \'\\xb1\'
查了一下是windows编码的问题:
在纯文本txt文件中代码默认保存方式为ASNI编码,而在windows中文操作系统中ASNI编码就是GBK编码,这时采用2个字节(16bit)保存一个字符。而我创建文件的时候是直接先用txt文件编写代码,然后直接修改后缀名为.py!!!!!没有修改编码方式。
这样程序文件就以GBK方式被保存下来,而python3中默认文件编码是UTF-8,默认字符文本的格式为unicode。
python在执行时识别该文件格式并不是UTF-8,所以就报错了。
如果将程序代码txt文件另存为如下图的UTF-8编码格式,再次执行时代码文件格式与python3默认文件格式一致,就不会报错了。同时在命令行也可以正确显示中文字符了。
这是因为python3中默认字符文本格式为unicode,windows中文操作系统中的命令行默认编码是ANSI,也就是GBK(命令行右击属性里查看),unicode可以兼容GBK,所以即使不用编码和解码也可以正确显示。
.py文件的运行:
如果想在浏览器中运行该文件,不能直接打开该文件必须用index.html文件作为引导,否则只是一个文本文件而已,浏览器不会自动运行的。
-
问题解决:
文件创建方式问题:
将.py文件回复为.txt文件,然后打开.txt文件用另存为的方式修改编码方式,windows这里还是比较人性的,可是这个没注意就要倒霉了。不过只能说自己是菜鸟吧。
.py文件的运行:
用index.html文件作为引导运行该.py文件。
test.py代码:
import cgitb
cgitb.enable()
print("Content-type:text/html\n")
print("hello,world!")
然后在浏览器中localhost:8000打开就可以看到结果了
-
问题总结:
这个问题很基础,是学计算机语言的一个必注意项,但是对于新手朋友们都很难意识到。
在内存中字符都是以unicode形式编码的,譬如说当我们新建一个txt来保存纯文本时,当我们在其中任意输入一个汉字字符时,首先是写入到内存中去的,这一步就是将操作系统中的汉字GBK编码转换成了unicode编码写入内存的,当我们单击默认形式保存时,此时内存中的unicode编码形式的汉字又被转换成GBK编码存储到磁盘中去的。举个例子来说,我们新建一个hello.txt文本以默认方式保存,并在其中写入“你好啊,欢迎您!”8个汉字字符,在命令行运行下面程序:
f = open(r'D:\hello.txt','r')
print(f.tell())
>>>0
print(f.read(2))
>>>你好
print(f.tell())
>>>4
第一次用f.tell()打印出来程序开始时磁盘文件中字符的指针默认开始处,当我们读取2个汉字字符后,文件指针指向就向后移动了2个汉字字符,因为在GBK中汉字字符默认2个字节,所以指针指向了4,再次打印f.tell()后显示的也是4。可见文件在磁盘中是以GBK编码保存的。