1
Posted on 上午12:57:00 by Fan Zhang and filed under

  使用 IDLE 运行 Python 程序的时候输出是即时的,但是在命令行下调用 .py 文件的时候,Python 对标准输出默认是有缓冲管理的。也就是说,在程序中尽管 print 试图输出好几行,但是在终端上并没有显示。只有当输出内容足够多的时候才会一起显示。

  之前在配置 Notepad++ 的插件 NppExec 时就遇到了这个问题(见使用 Notepad++ 编辑运行 Python 程序最后一部分)。

  Python 提供一个 -u 参数,使用它可以实现无缓冲的 IO(详细说明可以查看 Python --help)。

  Python 3.0 版本的 -u 参数似乎有一个 bug: Issue4705 (Revision 68451)。安装 3.1 应该就没问题了。

  不过即使使用了 -u 参数,也是指行缓存为 0,每当遇到一个换行符的时候才会输出。如果想在任意地方刷新缓冲区以达到立即输出的目的,需要在 print() 后使用 sys.stdout.flush()。(不知道还有没有更好的方法?)

  这里谈的是标准输出的缓冲,对于其他对象,比如文件,也会涉及到类似的输入输出缓冲的问题。

2
Posted on 上午12:50:00 by Fan Zhang and filed under

  今天我写了一个处理 Google Reader API 的 Python 模块,当我在其他程序中 import 这个模块的时候,第一次运行(在生成 pyc 文件之前)顺利通过,第二次运行就失败,显示如下错误:

Traceback (most recent call last):
 File "test.py", line 1, in <module>
  import readerapi
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 36-37: invalid data

  但是我尝试在 Notepad++ 中将文件编码进行改变:ANSI、带 BOM 的 UTF-8、不带 BOM 的 UTF-8,始终都是失败。

  后来我尝试把文件从桌面(这个路径含有空格和中文)转移到一个简单的路径,运行就没有问题。

  折腾了半天未果,怀疑是 3.0.1 有 bug,下载安装 Python 3.1 alpha 1 就好了=.=!

  

3
Posted on 下午6:40:00 by Fan Zhang and filed under ,

  Notepad++ 是一个开源的文本编辑器,功能强大而且使用方便。编辑和调试 Python 程序使用什么编辑器或者 IDE 不同人有不同见解。在不考虑使用调试工具的情况下,Vim 或者 Emacs 用户自然可以无视其他编辑器,不过在 Windows 环境下,使用 Notepad++ 之类的编辑器也是很好的选择。

  我是在 PortableApps.com 上下载的 Notepad++ Portable,它的好处是可以在每次关闭程序的时候把所需的配置文件单独保存,省却每台机器上重新配置的烦恼。

Tab长度和空格转换

  因为 Python 对缩进要求严格,我们将 Tab 设置成4个空格,在 "设置->首选项->编辑->制表符设置" 中修改。

语法高亮

  只要正确设置了扩展名,Notepad++ 就会自动识别语言并进行语法高亮。如果对高亮的颜色或者字体不满意,在 "设置->语言格式设置" 中可以进行修改。

自动完成

  Notepad++ 也提供了自动完成和输入提示功能,在 "设置->首选项->备份与自动完成" 中可以设置。Python 的自动完成所需的文件在安装的时候自带了,存放在 "YOUR_NPP_DIR\plugins\APIs"(详见官方FAQ:Auto-completion)。默认的快捷方式是 Ctrl+Space 和 Ctrl+Enter,可能和输入法的快捷键冲突,不过 Notepad++ 的所有快捷键都可以自定义。

运行程序

  点击 "运行->运行" (默认快捷键是 F5 ),在弹出的菜单中输入:

cmd /k C:\Python30\python.exe "$(FULL_CURRENT_PATH)" & PAUSE & EXIT

选择 "保存",就可以给这条命令设置一个快捷键并起一个名字,比如叫 "Run Python"。以后运行直接按自定义的快捷键就可以了。注意如果想修改这个快捷键,可以在 "设置->管理快捷键->Run Commands" 中修改。还有几点说明:

  1. 如果想修改这条命令,目前只能通过修改 shortcuts.xml 文件,这个文件保存在 Notepad++ 的配置文件中,可能在 Notepad++ 的目录,也可能在 Documents and Settings 下的 Application Data 内。
  2. $(FULL_CURRENT_PATH) 的含义是当前文件的完整路径,这是 Notepad++ 的宏定义,更多的相关宏可以参见官方FAQ:Run external tools。注意要用引号括起来,防止路径中间有空格。
  3. 直接执行 python.exe 在运行结束后窗口会自动关闭,所以要用 cmd 来执行。(在 Python 2.5 似乎有所不同,但是 3.0 需要这样设置。)
  4. cmd /k 的含义是执行后面的命令,并且执行完毕后保留窗口。& 是连接多条命令。PAUSE 表示运行结束后暂停,等待一个任意按键。EXIT 表示关闭命令行窗口。如果使用 cmd /c 就可以省掉 EXIT 了。

更多 Plugin

  因为 Notepad++ 支持插件扩展,所以可以使用很多有用的插件(下载页面有插件列表)。比如有一个插件:NppExec,可以在 Notepad++ 中增加一个 Console 窗口,使得运行命令和脚本更加方便。可以通过这个插件设置 Python 的运行命令。

  不过这个插件有个问题是只有程序运行结束了才会返回输出结果,这样就没法实时观察程序的运行了。不知道有没有好的解决方法?

2009-03-14Up:

  关于输出不及时问题,可以通过刷新 stdout 缓冲来解决。

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 来编码。不过就要手动实现把编码后的参数用"&"连接起来了。