2
Posted on 下午6:38:00 by Fan Zhang and filed under

  前几天决定尝试下 Python 3.0,安装的版本是 3.0.1。不出意外,原来的代码都不能用了。

  我想要修改的是使用 Python 登录网站中的程序,经过把 print 语句改成函数,重新查找标准库的用法,修改字符串的表达方式这些常规的修改,终于不提示语法错误了。

  不过我运行程序,却发现没有登录成功。经过调试,发现在发送登录请求的时候,编码出了问题。论坛需要 GBK,而 Python 使用 urlencode 编码得出的是 UTF-8。

  在 Python 3 中取消了原来的 unicode 类型,现在的字符串类型为 str,并且存放的就是 unicode 字符串。这样,在 Python 程序内部就不用为各种字符编码困扰了。现在使用字符串,只要保证在与外界交互,即读取(比如赋值、从文件读、从网络读)和输出(比如存储文件、发送信息)的时候使用正确的编码即可。但是这样也就造成原来很多程序都要重新写。

  字符串经过具体编码,就不再是 str 了,而是 bytes 类型。对一个 str 可以用个 encode 编码成 bytes 数据,而一个经过编码的 bytes 数据可以通过 decode 解码成 unicode 字符串。在 Python Docs: What's New In Python 3.0 : Text Vs. Data Instead Of Unicode Vs. 8-bit 中有详细说明。

  在读取文件的时候,默认是以 text mode 打开的,所以读取的资料直接可以存放到 str 字符串中,同时在 open 的时候可以指定编码系统。而如果文件不是文本,则需要在 open 的时候使用 "b"以 binary mode 打开。

  回到之前那个论坛登录程序,我使用标准库自带的 urlencode 将个人用户名和密码等参数进行 URL 编码,而由于 Pyhton 字符串机制发生根本变化,这个函数默认将文字(比如用户名是中文)按照 UTF-8 进行编码。而论坛需要的是 GBK 编码,所以造成无法登录。

  通过查看标准库相关的代码:Lib\urllib\parse.py 文件中的 urlencode 函数可以看出,它默认使用的就是 UTF-8,也没有提供可选的编码参数。所以要想实现 GBK 编码,只能放弃使用 urlencode 函数,直接使用 quote_plus 来编码。不过就要手动实现把编码后的参数用"&"连接起来了。

2
评论 : Python 3.0 中的编码和字符串
Joe 说... 2009年4月1日 上午9:42

在文件头部添加一行编码声明可否?
# coding=gbk

晓月 说... 2009年4月1日 上午10:59

to Joe:
我看了urlencode的代码,这个函数调用quote_plus的时候直接试用了UTF-8
文件头部加入编码声明现在来看似乎只和打开和执行文件有关

发表评论