第15章 其他内容

在Google中,Python是三种“官方语言”之一,另外两种是C++和Java。

——Greg Stein,2005年3月

(在SDForum会议上所说的话)

本章内容:

Jython;

Google+。

与第14章类似,本章介绍Python编程其他方面的内容,由于篇幅有限,这里只做简要介绍。作者希望本书将来出新版本时,可以将本章的每一节都扩充为完整的一章。本章首先介绍Java和Jython编程,然后讨论Google+API。

15.1 Jython

本节将介绍如何使用Jython在JVM中运行Python。首先介绍什么是Jython,以及其与Python工作方式的异同。接着介绍一个使用Swing的GUI示例。虽然通常人们使用Java的目的不是开发GUI程序,但这个示例能很好对比Java编写的代码,以及Jython中等价的Python版本。在本书将来的新版本中,希望能介绍更多的Java转Python版本的实例。

15.1.1 Jython简介

Jython是一根纽带,联系着两种不同编程环境的人群。首要原因是其适合Python开发者在Java开发环境中使用Python快速开发方案原型,并无缝地集成到已有的Java平台中。另一个原因是通过为Java提供一个脚本语言环境,可以简化无数Java程序员的工作。Java程序员无须为测试一个简单的类而编写测试套件或驱动程序。

Jython提供了大部分Python功能,且能够实例化Java类并与之交互。Jython代码会动态地编译成Java字节码,还可以用Jython扩展Java类。通过Jython,还能使用Java来扩展Python。用户能方便地在Python中编写一个类,在Java环境中就如同原生的Java类来使用。甚至可以把Jython脚本静态地编译为Java字节码。

读者可以从本书网站或http://jython.org下载Jython。在首次运行Jython交互式解释器时,它会显示一些提示信息,告知用户执行了一些.jar文件,如下所示。

$ jython

sys-package-mgr: processing new jar, '/usr/local/jython2.5.2/

jython.jar'

sys-package-mgr: processing new jar, '/System/Library/Java/

JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar'

sys-package-mgr: processing new jar, '/System/Library/Java/

JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext/sunpkcs11.jar'

Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06)

[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_26

Type "help", "copyright", "credits" or "license" for more information.

>>>

启动Jython交互解释器感觉就像在用Python一样。当然,可以执行Python中相同的“Hello World!”。

$ jython

Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06)

[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_26

Type "help", "copyright", "credits" or "license" for more information.

>>> print 'Hello World!'

Hello World!

更有趣的是,可以在Jython交互式解释器中使用Java编写“Hello World!”。

>>> from java.lang import System

>>> System.out.write('Hello World!\n')

Hello World!

Java为Python用户带来了一些额外的好处,如可以使用Java原生的异常处理(在标准Python中是无法使用Java的异常的,当与其他Python实现做比较时,标准Python都是指 CPython),并使用 Java的垃圾回收器(这样就无须在 Java中重新实现 Python的垃圾回收器了)。

15.1.2 Swing GUI开发示例

由于Jython能够访问所有Java类,因此能做的事就太多了。比如 (GUI开发。在Python中,用Tkinter模块中的Tk作为默认GUI工具包,但是,Tk不是Python的原生工具包。然而,Java有原生的Swing。通过Jython,可以用Swing组件写一个GUI应用程序。注意,不是用Java,而是用Python编写。

示例15-1是使用Java编写的一个简单的“Hello World!”GUI程序,其后的示例15-2是对应的Python版本。这两个版本都模仿了第5章中的Tk例子tkhello3.py,分别名为swhello.java和swhello.py。

示例15-1 Java版的Swing“Hello World”(swhello.java)

与tkhello3.py相同,这段程序使用Swing创建一个GUI,而不是Tk。但使用的语言是Java。

第15章 其他内容 - 图1

第15章 其他内容 - 图2

示例15-2 Python版的Swing“Hello World”(swhello.py)

这段Python脚本的功能与前面的Java程序完全相同,由Jython解释器执行。

第15章 其他内容 - 图3

这两段代码的功能与tkhello3.py完全相同,区别仅在于用Swing替换了Tk。下面会同步介绍这两段代码。

代码解释

在开头,swhello.java和swhello.py都导入所需的模块、库和包。两个程序中的下一部分使用Swing原语(primitive)。在 Java代码块中完成了quit回调,而在Python代码中,在进入程序的核心之前定义了quit函数。

接着定义了小组件,在此之后的代码将这些小组件放置到 UI 中合适的位置。最后的行为是将所有内容放到内容面板中,打包所有的小组件,最后让整个用户界面可见。

Python版本的特点是其代码量远小于对应的Java版本。Python版本的代码更易理解,每行代码更加精炼。简而言之,就是冗余更少。为了让程序能够工作,Java代码含有更多的样板代码。使用Python可以关注于应用中的重要部分,即需要解决问题的解决方案。

因为这两个程序都会编译成Java字节码,所以在同一个平台上,两个程序看上去完全相同就没什么好奇怪的了(见图15-1)。

第15章 其他内容 - 图4 图15-1 Swing的Hello World示例脚本(swhello.java和swhello.py)

Jython是一个很强大的工具。因为用户能够同时得到了Python强大的表达能力,以及Java库中丰富的API。如果读者现在是一个Java开发者,希望我们已经引起了你对Python强大功能的兴趣。如果读者是Java新手,Jython能够让简化工作。可以用Jython写原型,然后在必要的时候,轻松地移植到Java中。

15.2 Google+

本节介绍Google的社交平台——Google+。首先介绍什么是Google+,接着讨论如何在 Python 中连接 Google+。最后,通过一个简单的代码示例介绍一些能通过 Google+和Python完成的事情。因为Google+一直在增加新特性,所以在本书将来的版本希望能介绍更多的功能。

15.2.1 Google+平台简介

Google+可以理解为含有API的另一个社交平台。也可以从企业的视角来理解它,即Google+将Google的许多产品组合到一起,作为已有特性集的增强版本,这也是其名称由来——Google+。

无论怎么理解,Google+都与社交有关,并与Google的许多产品一样,有相应的API。用户可以通过 Google+发布消息和照片。还可以关注其他人的动态,单击动态中的“+1”按钮来告诉对方喜欢这条消息。用户可以评论,也可以分享,Google+会把消息发送到朋友圈中,或公开发布。

前面提到了 Google+有 API。在本书编写之际,开发者可以使用这个 API 访问并搜索Google+的用户和动态,包括对这些消息的动态评论。开发者还可以编写应用来集成Google+的Hangouts,因为后者也有API。这些API能够让开发者编写应用来搜索公开发布的消息,并获取用户的个人资料。下面来看一个实例。

15.2.2 Python和Google+API

在Python中访问Google+的功能很简单。但在这个简要介绍中,连认证相关的内容都不会介绍(如果编写的应用获得了相应的授权,就可以访问Google+的更多数据),所以这个例子比一般情况还要简单。

在开始之前,必须首先安装Google API的Python版客户端程序库。如果还没有安装,可以方便地通过pip或easy_install这样的工具来安装。(对于2.x,需要Python 2.6或之后的版本;对于3.x,需要Python 3.4及以上的版本。如果使用easy_install,更新和安装命令如下所示。

$ sudo easy_install —upgrade google-api-python-client

注意,这个库不仅可以用来访问Google+ API,还可以访问许多其他Google服务。在这个http:// code.google.com/p/google-api-python-client/wiki/SupportedApis中可以找到完整的API支持列表:

下一步,需要一个访问密钥。访问http://code.google.com/apis/console并创建一个新的项目。在新创建的项目中选择Services标签,启用Google+ API。接着,选择API Access标签,复制API密钥,将其粘贴到下面的代码中。更好的处理方式是将代码中的私密数据(如凭证信息)重构到独立的文件中。完成了这些工作,就可以开始了。

15.2.3 一个简单的社交媒体分析工具

示例 15-3 显示的是一个简单的社交媒体分析工具。通过这个工具,可以看到人们在Google+上对某个特定话题发表的消息。但各个消息的地位并不是相等的,有些消息的阅读人数很少,有些则会被评论和分享很多次。

在这个应用中,我们只关注热门信息。无论是使用“Python”作为搜索关键词,还是用户自己选择的关键词,应用都会根据热度排序,列出搜索结果中过去一周内排名前五的消息。该程序还有另一个小功能,它能够查询并显示一个Google+用户的个人资料。

脚本的名称为plus_top_posts.py,但在查看代码之前。先来看看下面这个例子,这是一个菜单驱动的程序,通过这个程序可以了解程序的运作方式。

$ python plus_top_posts.py


Google+ Command-Line Tool v0.3


(p) Top 5 Python posts in past 7 days

(u) Fetch user profile (by ID)

(t) Top 5 posts in past 7 days query

Enter choice [QUIT]: p

* Searching for the top 5 posts matching 'python' over the past 7

days…

From: Gretta Bartels (110414482530984269464)

Date: Fri Nov 25 02:01:16 2011

Chatter score: 19

Post: Seven years old.Time to learn python.And maybe spelling.

Link: https://plus.google.com/110414482530984269464/posts/MHSdkdxEyE7


From: Steven Van Bael (106898588952511738977)

Date: Fri Nov 25 11:00:50 2011

Chatter score: 14

Post: Everytime I open a file in python I realize how awesome the

language actually is for doing utility scripts.f =

open('test.txt','w') f.write('hello world') f.close() Try doing that in java

Link: https://plus.google.com/106898588952511738977/posts/cBRko81uYX2


From: Estevan Carlos Benson (115832511083802586044)

Date: Fri Nov 25 20:02:11 2011

Chatter score: 11

Post: Can anyone recommend some online Python resources for a

beginner.Also, for any python developers, your thoughts on the

language?

Link: https://plus.google.com/115832511083802586044/posts/9GNWa9TXHzt


From: Michael Dorsey Jr (103222958721998092839)

Date: Tue Nov 22 11:31:56 2011

Chatter score: 11

Post: I slowly but surely see python becoming my language of choice.Programming language talk at the gym.Must be cardio time.

Link: https://plus.google.com/103222958721998092839/posts/jRuPPDpfndv


From: Gabor Szabo (102810219707784087582)

Date: Fri Nov 25 17:59:14 2011

Chatter score: 9

Post: In http://learnpythonthehardway.org/ Zed A.Shaw suggest to read code backwards.Any idea why would that help? Anyone practicing

anything like that?

Link: https://plus.google.com/102810219707784087582/posts/QEC5TQ1qoQU



Google+ Command-Line Tool v0.3


(p) Top 5 Python posts in past 7 days

(u) Fetch user profile (by ID)

(t) Top 5 posts in past 7 days query

Enter choice [QUIT]: u

Enter user ID [102108625619739868700]:

Name: wesley chun

URL: https://plus.google.com/102108625619739868700

Pic: https://lh3.googleusercontent.com/-T_wVWLlmg7w/AAAAAAAAAAI/AAAAAAAAAAA/zeVf2azgGYI/photo.jpg?sz=50

About: WESLEY J.CHUN, MSCS, is the author of Prentice Hall&#39;s bestseller, <a href="http://corepython.com"><i>Core Python

Programming</i></a>, its video


Google+ Command-Line Tool v0.3


(p) Top 5 Python posts in past 7 days

(u) Fetch user profile (by ID)

(t) Top 5 posts in past 7 days query

Enter choice [QUIT]:

$

现在来看程序的代码。

示例15-3 简单的社交媒体分析工具(plus_top_posts.py)

这个Python 2脚本在Google+中搜索匹配的消息和用户个人资料。

第15章 其他内容 - 图5

第15章 其他内容 - 图6

第15章 其他内容 - 图7

逐行解释

第1~12行

很有趣的是,即使这个脚本在本书中算是长的,但其中只有两条import语句。一条导入了标准库中的datetime包,另一个导入了Google API的Python版客户端库。关于后者,只关注API中的build()函数。实际上,这一部分非常简单的原因是没有处理安全方面(即授权)的问题。在本章末尾有与授权相关的练习。

在这段代码的最后一部分列出了需要用到的常量。WIDTH和HR变量只与用户的显示有关。API_KEY用于验证Google,使用Google+上获取公开数据的API。这里强烈建议将这个值从逻辑代码中移走,放到另一个文件,(如 secret.pyc)中,以更好地保证安全性。只有在其他用户可以访问你的文件时,才提供这个secret.pyc文件(.pyc文件并不能保证万无一失,但其需要入侵者了解Python虚拟机内部工作机制才能逆向解码)。如果缺少API_KEY,本章之前的部分介绍,如何获取API密钥。

MAX_DEF是默认显示的结果数目,MAX_RES是目前可以从Google+API获得的最大搜索结果数目,MAX_TOT是当前允许使用该脚本进行搜索的最大用户数目,UID是默认的用户ID(表明你是谁)。

第14~17行

PlusService类提供了访问Google+ API的主接口。在init()初始化函数中,通过调用apiclient.discovery.build()连接API,传递所需的API(Google+用“plus”及其版本号表示)和API密钥。

第19~39行

get_posts()方法完成主要工作,包括设置和过滤,以及从Google获取数据。它首先初始化结果列表(即posts),设置从Google请求的最大数目(必须小于等于MAX_RES),缓存API链接,生成对Google+API的初始调用,在请求成功时返回handle。其中的while循环确保进行无限循环,直到API不再返回更多的结果。有其他方式可以摒弃这个循环,下面会介绍。

使用链接 handle执行查询并从Google+获取 feed。从网络上传回的是JSON格式,它会转换成Python字典。如果在源(feed)中含有条目(即含有键名为“items”的元素),就循环遍历,获取并保存数据。否则,就没有数据,跳出循环并返回中间结果。在这个循环中,还可以根据时间戳来退出。由于API返回的内容按时间逆序排列,因此当获取的内容时间戳距当前超过了一周,就会知道所有剩下的消息都是老的,于是可以安全地退出并返回数据集。

时间比较通过直接比较ISO 8601/RFC 3339格式的时间戳完成。所有发送过来的Google+消息都使用这种格式,因此本地的时间戳必须从datetime.datetime对象转换成与ISO等价的形式。详见top_posts()中的转换描述,接下来就会看到。

下一个是过滤掉标题中不含有搜索关键字的消息。这种搜索可能不是最精确的,因为关键字可能会出现在附件或整个正文内容中。在本章末尾有练习来改进这种过滤方式。这是这段代码最后一次过滤,读者可以在这里添加其他过滤功能。

当消息通过了这些测试后,将过滤后符合要求的消息传递给PlusPost的初始化函数,创建一个新的PlusPost对象。

接下来,检查是否已获得最大数量的结果。如果已获得,就返回结果并退出。否则,调用Google+的API的search_next()方法,将当前链接的handle传递进去,让该方法知道上次离开的地方(是的,就像游标一样)。

最后一个else子句用于处理search返回结果为空的情形。

第41~44行

该类中的最后一个方法是get_user()。因为这个实例侧重的是用户(people),而不是消息状态(activity),所以使用 self.service.people()代替 self.service.activity()。这里期望的特定行为是get()通过ID获取特定Google+用户的信息。

这一部分中最后一行代码提供了一个工具函数(scrub()),用来将多行文本中的多个空格替换为单个空格,以此将其转成单行文本。这样有助于在命令行脚本中控制输出内容,但等价的Web应用却不并需要这个功能。

第46~61行

PlusPost 对象的目的是创建与消息数据等价的对象,但其中的内容精简并修正过,只含有所需的数据。该对象表示用户发布的单条Google+消息。Google+ API返回一个嵌套层次非常高的JSON数据结构对象和数组,分别转换成Python字典或列表,它们使用起来有些困难。这个类将这些数据结构转成平坦的对象,将重要的属性显示为实例变量。

消息的标题和内容经过处理,URL未做修改,但时间戳变得更加易读。保存的原始发布者的信息包括显示名称(displayName)和 ID,后者可以用来查询该用户的更多信息。消息的时间戳会从ISO 8601/RFC 3339转换成Python本地的datetime.datetime对象,接着赋值给self.when。

“chatter score”用来衡量消息的影响和相关性。chatter为一则消息“+1”、评论、分享的总次数。chatter分越高,则该消息对社交媒体分析工具更重要。把这些信号发送给“object”数据结构,分别填充对应部分的totalItems字段。接着使用生成器表达式生成获取每一列的数值,然后使用sum()计算总和,赋值给self.chatter。

如果读者是Python新手,可以使用下面的代码,这是第60~61行代码更直观的版本。

self.chatter = api_record['object']['replies']['totalItems']\

  • api_record['object']['plusoners']['totalItems']\

  • api_record['object']['resharers']['totalItems']

相比最初版本的代码,这里做了若干优化。下面是优化的内容及原因。

1.原先多次使用api_record['object']来查询属性。如果这段代码只运行几次,还不是个大问题。但如果每天在服务器上执行几百万次,则它最终会影响到效率。常见的Python最佳实践是用一个局部变量存储其引用,如obj = record['object']。

2.需要获取不同列中相同的名称(“totalItem”),所以将不同列存入了cols对象来重用。

3.这里没有通过加号手动添加值,一般会用sum()这样的内置函数,因为这些内置函数由C编写,效率比纯Python高。

4.如果需要添加其他衡量指标来提高 chatter 分数,会增加代码长度,如“+api_record ['object'][SOMETHING_ELSE]['totalItems']”,现在只须向列字段添加一个单词即可完成,例如,cols = ('replies', 'plusoners', 'resharers', SOMETHING_ELSE)。

这里最重要的一个目标就是让代码符合 Python 风格,即可读、简单、优雅。原先和改进后的解决方案能很好地满足要求。但如果chatter分数需要计算10个值的总和,就会显现出差异。

再次回到上面的话题,虽然与Google+ Ripples有些类似,但chatter并不是完全相同。因为Ripples更像是一个可视化地提供消息的chatter分数(关于Ripples的更多内容可以访问这两个链接:http://googleblog.blogspot.com/2011/10/google-popular-posts-eye-catching.htmlhttp://google.com/support/plus/bin/answer.py?answer=1713320)。

第63~82行

top_posts()函数用于在用户界面显示查询的消息。它显示一条消息表示开始查询,接着整理并对结果排序,最后逐个显示给用户。该函数调用 sorted()内置函数对消息按 chatter 分数降序排列。

默认情况下,应用显示前5条匹配度最高的消息。调用者可以通过第79行的if语句修改这个行为。另一处可以控制的地方是组成完整数据集的整组消息。

第84~90行

find_top_posts()函数用于在用户界面向用户提示搜索关键字,接着调用top_posts()进行查询。如果用户没有提供任何搜索关键字,则使用默认的“python”。py_top_posts()是自定义函数,直接使用“python”搜索关键字调用find_top_posts()。

第92~103行

find_user()函数与find_top_posts()类似,只是其任务是获取用户ID,接着调用get_user()来完成任务。该函数会确保用户输入的ID是数字,并将结果显示到屏幕上。

第105~124行

最后一块代码提供了_main()函数,用来向用户显示一个含有不同选项的菜单。该函数首先解析用于表示菜单的字典menu,接着插入样板文本。然后提示用户输入选项,如果选项正确则执行。否则,默认情况下该脚本将退出。

Google+目前依然是相对较新的系统,在其今后的发展中,许多内容都会改变或增强,要对此有所准备。与前面一节类似,这里仅仅稍微接触了一下Google+平台及其API。与Jython类似,希望这个的简单示例和对应代码能够激发读者的兴趣,进一步了解相关技术并激发出一些可行的想法。在本书将来的新版中,可能会扩展这些章节!

15.3 练习

Java、Python、Jython

15-1 Jython。Jython和CPython之间有什么区别?

15-2 Java和Python。将一个已有的Java应用移植到Python中。记录下移植过程中的经验。完成后,总结需要完成哪些事情,包括有哪些重要的步骤,以及执行哪些常见的操作。

15-3 Java和Python。学习Jython源码。描述一些Python标准类型是如何在Java中实现的。

15-4 Java和Python。使用Java编写Python扩展。其中有哪些必要步骤?通过Jython交互式解释器演示最终结果。

15-5 Jython和数据库。在第6章找到一个感兴趣的练习,将其移植到Jython中。(目前)最好使用Jython 2.1[5],该版本自带zxJDB这个JDBC数据库模块,基本与Python DB-API 2.0兼容。

15-6 Python和Jython。找到 Jython中目前不支持的一个Python模块,将其导入Jython中。尝试向Jython提交一个补丁。

Google+

15-7 结果的数量。在 plus_top_posts.py 中,对显示结果的数量进行了限制,只显示最高的5个,但代码明显可以支持更多结果。添加一个新的菜单项,让用户选择选择显示多少个结果(需要是一个合理的数字)。

15-8 时间线。在top_posts()中,有一个ndays变量,默认情况下让脚本获取过去7天最火的消息。通过变量timpleline(任意天数)来扩大覆盖范围。

15-9 面向对象编程与全局变量。在 plus_top_posts.py 中,将所有核心功能放进了PlusService类中。所有面向用户的代码(raw_input()和print语句)都位于该类之外的函数中。

a)这种方式需要用到全局变量service。这样有什么坏处?

b)重构这些代码,让外部函数不再访问全局变量service。可以考虑下面的方式:将外部函数集成进 PlusService(包括_main()),作为其中的方法;将全局变量作为局部变量传递等。

15-10 Python 3。针对Python的Google API客户端库目前还不支持Python 3,但正在开发中 [6]。将plus_top_posts.py转换成等价的Python 3 形式,或创建可以同时运行在Python 2或3中的代码。当Google API支持Python 3时,就可以测试这些代码(验证它是否支持Python 3)。

15-11 进度条。“正在搜索…”这则消息有助于让用户了解当前状况并等待处理结果。为了做到这一点,向plus_top_posts.py添加sys模块。接着在PlusService.get_posts()中,在向结果添加新的PlusPost对象的代码后面,添加向屏幕输出单个点号的代码。建议使用 stderr,而不是 stdout,因为前者不使用缓存,会直接显示到屏幕上。在执行其他搜索时,就会认识到这些内部工作在显示之前需要综合到一起。

15-12 Google+。用户可以通过评论对消息进行反馈。在 plus_top_posts.py 中,只列出了消息。改进相关功能,让应用还可以显示每则消息的评论。更多内容可以访问https:// developers.google.com/+/api/ latest/comments。

15-13 授权。目前在plus_top_posts.py中的所有搜索都是未授权的,意味着应用只能搜索公共数据。添加对OAuth2的支持,让应用可以访问用户和私有数据。更多内容可以访问下面两个链接:https://developers.google.com/+/api/oauth和http://code.google.com/p/google -api-python-client/wiki/OAuth2Client。

15-14 精确度。在搜索代码中,plus_top_posts.py 脚本,特别是 get_posts()方法中,过滤掉了不相关的内容。这里只确保搜索关键字出现在消息的标题中。这样做有些不准确,因为标题仅仅是消息全文的一部分。检查消息内容是否也含有搜索关键字,以此来提升过滤的准确度,如果某篇消息匹配了一个关键字,则保存这条消息。可以查看PlusPost对象的初始化函数来了解如何获取消息内容。尽量减少代码重复量。选做题:检测附件内容中是否含有搜索关键字。

15-15 时间与相关度。Google+默认搜索顺序是最新的消息在最前面。在调用self.service.activites().serach()的过程中,通过orderBy='recent'参数指明。关于orderBy的更多内容可以访问开发者文档,参见 https://developers .google.com/+/api/latest/activities/search。

a)这个排序方式可以从时间优先改为相关度优先,即将参数改为“best”。执行这项改动。

b)这个参数如何影响get_post()方法中的代码?原来的get_post()会忽略掉超过期限的消息。

c)这里要解决哪些问题?如果有的话,请解决。

15-16 用户搜索。通过Google+API,创建一个名为find_people()的函数,添加对用户的搜索。当前状态可以使用 self.service.activities.serach()方法搜索。用户搜索等价的方法,即self.service.people().search()。更多信息请访问http://developers.google.com/+/api/latest/people/ search。

15-17 附件。plug_top_posts.py脚本没有处理附件内容,附件有时是一则消息的关键因素。在执行脚本后显示出来的前5条与Python相关的消息中(本书编写时),至少有一则消息含有相关 Web 页面的链接,还有至少一条消息含有图片。对该脚本添加对附件的支持。

15-18 命令行参数。本章的plus_top_posts.py是命令行菜单驱动的程序。但在实际中,有时可能更希望是非交互的界面,特别是对于脚本任务、计划任务等。改进应用,集成命令行参数解析接口(以及相应的功能)。建议使用argparse[7]模块,但optparse[8]或较老的getopt也可以完成任务。

15-19 Web 编程。plus_top_posts.py 脚本作为命令行工具运行时一切正常,但用户可能不会一直使用命令行,有时只能在线访问。开发一个完全独立的Web 版应用。

读者可使用任何所需的工具。


[1].原文语出“看不见的大猩猩”心理学实验。——译者注

[2].已核实,依然是最新版本,这几年没有更新。——译者注

[3].即SOAP和JSON-RPC的缩写。——译者注

[4].练习14-15。——译者注

[5].现在建议使用Jython 2.7版本。——译者注

[6].现在支持Python 3.3以上。——译者注

[7].Python 2.7中新增。

[8].Python 2.3中新增。