初步介绍Python中的pydoc模块和distutils模块


Posted in Python onApril 13, 2015

pydoc

Ka-Ping Yee 曾创建了一个相当著名的模块,名叫 pydoc (比较而言: pydoc 可以做到 perldoc 所能做的任何事,并且做得更好、更漂亮:-)。对于 Python 2.1 来说, pydoc (以及它支持的 inspect )是标准库的一部分。而对于使用 Python 1.5.2、1.6 或者 2.0 版本的用户来说,下载并安装 pydoc 也很简单 ? 请立即下载(请参阅 参考资料)。

作为提供给阅读这篇 Python 文章的任何初学者的背景资料,Python 一直有些半正式的文档标准。这些标准并没有试图过度地限制开发者,而是给开发者提供“一种明显的写文档的方法。”幸运的是,通常情况下,Python 开发者所写的文档比使用其它语言的典型开发者所写的要好得多。

Python 文档之所以“优秀”的主要因素是使用所谓的“docstring”。虽然 docstring 实际上只是一个被称为 _doc_ 的变量,但还是有一个普遍使用的创建它们的快捷方式:只要在模块、函数 def 、类定义或方法 def 的头部放入一个简单的由(三重)引号括起来的字符串。此外,还有几个接近标准的模块级的“魔术”变量名被经常使用。尽管那些文档规则不太正式,但几乎所有第三方的模块和标准模块的文档都使用相同的模式。让我们来看一个使用大部分元素的简化示例:
清单 1: 附带典型文档的模块 mymod.py

#!/usr/bin/python
"""Show off features of [pydoc] module
This is a silly module to
demonstrate docstrings
"""
__author__ = 'David Mertz'
__version__= '1.0'
__nonsense__ = 'jabberwocky'
class MyClass:
  """Demonstrate class docstrings"""
  def __init__ (self, spam=1, eggs=2):
    """Set default attribute values only
    Keyword arguments:
    spam ? a processed meat product
    eggs ? a fine breakfast for lumberjacks
    """
    self.spam = spam
    self.eggs = eggs

pydoc 模块利用了 Python 文档的约定,又使用了一些有关 Python 导入、继承和其它类似的实用知识。此外, pydoc 有绝对的天赋可以使自己在不同的操作模式下被使用(马上就能看到更多有关这个论点的资料)。让我们用一些时间,看看通过 OS 命令行调用的 manpage 风格的用法。

假设您已将上述模块 mymod 安装在您的系统上,但不知道它有什么用处(在示例中并不多)。您可以阅读源代码,不过更简单的方法可能是:
清单 2:获取‘manpage'风格的文档

% pydoc.py mymod
Python Library Documentation: module mymod
NAME
  mymod - Show off features of [pydoc] module
FILE
  /articles/scratch/cp18/mymod.py
DESCRIPTION
  This is a silly module to
  demonstrate docstrings
CLASSES
  MyClass
  class MyClass
   | Demonstrate class docstrings
   |
   | __init__(self, spam=1, eggs=2)
   |   Set default attribute values only
   |
   |   Keyword arguments:
   |   spam ? a processed meat product
   |   eggs ? a fine breakfast for lumberjacks
DATA
  __author__ = 'David Mertz'
  __file__ = './mymod.pyc'
  __name__ = 'mymod'
  __nonsense__ = 'jabberwocky'
  __version__ = '1.0'
VERSION
  1.0
AUTHOR
  David Mertz

根据特定的平台和安装过程,上述样本可能会显示在一个允许滚屏、搜索等功能并突出显示某些关键字的文本查看器中。对于像这样简单的示例,只是比纯粹的阅读源代码好一点。但请考虑一下像下面这样简单的示例:
清单 3:检查类的继承结构

% cat mymod2.py
from mymod import MyClass
class MyClass2(MyClass):
  """Child class"""
  def foo(self):
    pass
% pydoc.py mymod2.MyClass2
Python Library Documentation: class MyClass2 in mymod2
class MyClass2(mymod.MyClass)
 | Child class
 |
 | __init__(self, spam=1, eggs=2) from mymod.MyClass
 |
 | foo(self)

在这个快速报告中,我们可以知道 MyClass2 有 __init__() 和 foo() 方法(以及相应的参数),哪个方法是类自身实现的以及其它哪些方法是继承而来(以及被继承的类所处的位置)。

另一个美妙的类似于 manpage 的功能是用来在模块中搜索关键字的 -k 选项。例如:
清单 4:为任务定位适当的模块

% pydoc.py -k uuencode
uu - Implementation of the UUencode and UUdecode functions.
% pydoc.py uu
Python Library Documentation: module uu
NAME
  uu - Implementation of the UUencode and UUdecode functions.
[...]

pydoc 除了它的命令行用法之外,还有其它四种“模式”可以显示被生成的同样的文档。

    Shell 模式:在 Python 交互式 shell 中,您可以导入 pydoc 的 help() 函数,这样就能够在不离开交互式会话的情况下获得任何对象的帮助。也可以只输入一个 help 进入交互式“help 解释器”。例如:

    清单 5:shell 模式下的交互式 help 解释器

#------- Interactive shell with help enhancements ------#
  >>> from pydoc import help
  >>> import uu
  >>> help(uu.test)
  Help on function test in module uu:
  test()
   uuencode/uudecode main program
  >>> help
  Welcome to Python 2.0! This is the online help utility.
  [...introductory message about help shell...]
  help>
  •     Web 服务器模式:仅使用 -p 选项, pydoc 就会在 LOCALHOST 上作为一个简单的 Web 服务器自启动。您可以使用任何 Web 浏览器浏览所有已安装在现有操作系统上的模块。这个服务器的主页是一张模块列表,根据目录(并用浏览器支持的醒目色块)将它们分组。此外,您查看其文档的每个模块也广泛分布着它导入的函数、方法以及指向任何模块的链接。
  •     HTML 生成器模式: -w 选项对于 pydoc 可以归档的任何文档都能生成 HTML 文档页面。这些页面与您在 Web 服务器模式下可能会浏览到的页面本质上是一回事,但页面是静态的,可以进行存档、传输等等。
  •     TK 浏览器模式: -g 选项将创建一个和 xman 或 tkman 风格很相似的“图形帮助浏览器。”

distutils

对于 Python 1.6 来说, distutils 包已经成为标准 Python 库的一部分。 distutils 包有两个目的。一方面, distutils 希望让最终用户觉得安装新模块、包和工具的过程一致而轻松。另一方面, distutils 还希望让新模块、包和工具的开发者觉得创建这些容易安装的分发包很轻松。让我们简要看一下这两个方面。

在最简单的情况下,开发者将已经选择为您特定的平台创建了安装程序。如果是这种情况,您其实根本不需要知道 distutils 的存在。目前, distutils 能够为支持 RPM 的 Linux 系统创建 RPM,为 Win32 系统创建 Windows EXE 安装程序。虽然这两个平台是主角,但还存在着其它平台,要么开发者可能已经有了适用于您的平台的解决方法(要么有创建一个安装程序的时间和兴趣)。

虽然没有最简单的例子,但幸运的是下一个出色的例子并没有复杂太多。假设您获取了一个支持 distutils 的源代码分发包,您可以依靠大量的东西(当然,在一切正常的情况下)。分发包的归档文件必须按照标准归档文件格式 ? 通常可以是 .zip 格式或 .tgz / .tar.gz 格式(偶尔会是 .tbz 格式或 tar.Z 格式, .sit 格式支持很快会添加到 MacOS 中去)。多数时候,Windows 用户使用 zip 格式文件,而 Linux/UNIX 用户使用 tarball 格式文件。不过要想在大多数平台上解包大部分的文件格式并不困难。一旦您将归档文件解包了,您就会获得一个文件集合,它被保存在与归档文件同名的目录里。例如:
清单 6:将一个 [distutils] 归档文件解包

E:\Archive\devel>unzip -q Distutils-1_0_2.zip
E:\Archive\devel>cd Distutils-1.0.2
E:\Archive\devel\Distutils-1.0.2>ls
The volume label in drive E is ARCHIVE.
The Volume Serial Number is E825:C814.
Directory of E:\Archive\devel\Distutils-1.0.2
 6-14-01  0:38a   <DIR>      0 .
 6-14-01  0:38a   <DIR>      0 ..
 5-03-01  6:30p   15355      0 CHANGES.txt
 5-03-01  6:32p   <DIR>      0 distutils
 5-03-01  6:32p   <DIR>      0 doc
 5-03-01  6:32p   <DIR>      0 examples
10-02-00 11:47p    373      0 MANIFEST.in
 5-03-01  6:32p   <DIR>      0 misc
 5-03-01  6:32p    496      0 PKG-INFO
 4-20-01  2:30p   14407      0 README.txt
 6-29-00 11:45p   1615      0 setup.cfg
 5-03-01  6:17p   1120      0 setup.py
 4-20-01  2:29p   9116      0 TODO
 4-11-00  9:40p    836      0 USAGE.txt

大多数模块分发包的文件和目录会比这个例子中显示的要少。你真正需要的仅仅是文件 setup.py ,其中包含安装指令。但实际上,大家一致希望目录中有其它文件,这样 setup.py 就有可以安装的东西了。这里,您需要做的是:

E:\archive\devel\Distutils-1.0.2> python setup.py install

至少那应该是您该做的事情。如果出现问题,请阅读(很可能也包含在 setup.py 中的) README.txt 或 README 文件。然后,再查阅 Greg Ward 的 Installing Python Modules 文档。(请参阅 参考资料)。

接下来该做什么呢?您可以通过名字来猜测, setup.py 其实只是普通的 Python 脚本,所以当它运行时可以做任何事。但在大多数情况下 setup.py 会有一种相当固定的格式。可能看上去像这样:
清单 7:最小的 setup.py 安装脚本

#!/usr/bin/env python
"""Setup script for the sample #1 module distribution:
  single top-level pure Python module, named explicitly
  in 'py_modules'."""
from distutils.core import setup
setup (# Distribution meta-data
    name = "sample",
    version = "1.0",
    description = "Distutils sample distribution #1",
# Description of modules and packages in the distribution
    py_modules = ['sample'],
   )

这里真正的工作是由导入的 distutils 实现,特别是由 setup() 函数来实现。基本上, setup() 函数采用一组包含一列需要安装的东西(除 py_modules 外还可能有 packages 或 ext_modules 或其它东西)的已命名的变量。

distutils 的魔力在于 创建模块分发包时利用安装时使用的完全相同的 setup.py 文件。一旦您 ? 模块开发者 ? 创建了一个 setup.py 脚本(也可能是‘setup.cfg'或其它扩展名)指定了需要安装的东西,创建分发包所要做的全部事情就是(下面的一步或几步):
清单 8:创建模块分发包

% python setup.py sdist
% python setup.py bdist_wininst
% python setup.py bdist_rpm

根据您指定的特定的分发包,您将创建一个标准的归档文件(tarball 或 zip 格式文件,取决于平台类型)或者一个完整的安装程序(像上面讨论过的那样)。

把两者结合在一起

虽然我们还没有完全达到目的,但是 Python 已经逐步成为最容易使用的编程语言的一种, 而且还是最容易使用的编程 社区的一种。虽然某些新的工具还有一些需要克服的缺陷,但在普遍意义上,让 Python 对用户透明这个要求已经实现了。

Python 相关文章推荐
python将html转成PDF的实现代码(包含中文)
Mar 04 Python
python两种遍历字典(dict)的方法比较
May 29 Python
Python温度转换实例分析
Jan 17 Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 Python
使用python存储网页上的图片实例
May 22 Python
对python sklearn one-hot编码详解
Jul 10 Python
Python中分支语句与循环语句实例详解
Sep 13 Python
详解如何用django实现redirect的几种方法总结
Nov 22 Python
Python 虚拟空间的使用代码详解
Jun 10 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
Feb 09 Python
Python操控mysql批量插入数据的实现方法
Oct 27 Python
python三子棋游戏
May 04 Python
Python随机生成数模块random使用实例
Apr 13 #Python
Python字典操作简明总结
Apr 13 #Python
Python单元测试框架unittest使用方法讲解
Apr 13 #Python
Python配置文件解析模块ConfigParser使用实例
Apr 13 #Python
深入Python函数编程的一些特性
Apr 13 #Python
Python命令行参数解析模块getopt使用实例
Apr 13 #Python
Python中文件操作简明介绍
Apr 13 #Python
You might like
PHP扩展开发教程(总结)
2015/11/04 PHP
Laravel相关的一些故障解决
2020/08/19 PHP
jquery ui 1.7 ui.tabs 动态添加与关闭(按钮关闭+双击关闭)
2010/04/01 Javascript
js setTimeout 常见问题小结
2013/08/13 Javascript
jquery查找tr td 示例模拟
2014/05/08 Javascript
JavaScript中数组继承的简单示例
2015/07/29 Javascript
js微信分享API
2020/10/11 Javascript
只需五句话搞定JavaScript作用域(经典)
2016/07/26 Javascript
Html5 js实现手风琴效果
2020/04/17 Javascript
学习使用jQuery表单验证插件和日历插件
2017/02/13 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
js中对象与对象创建方法的各种方法
2019/02/27 Javascript
vue实现搜索功能
2019/05/28 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
js滚轮事件 js自定义滚动条的实现
2020/01/18 Javascript
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
详解Python 数据库 (sqlite3)应用
2016/12/07 Python
Python简单的制作图片验证码实例
2017/05/31 Python
python matplotlib坐标轴设置的方法
2017/12/05 Python
Python操作Redis之设置key的过期时间实例代码
2018/01/25 Python
DataFrame 将某列数据转为数组的方法
2018/04/13 Python
Python实现的tcp端口检测操作示例
2018/07/24 Python
浅谈pycharm下找不到sqlalchemy的问题
2018/12/03 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
2020/01/10 Python
Python IDE环境之 新版Pycharm安装详细教程
2020/03/05 Python
python中tab键是什么意思
2020/06/18 Python
使用phonegap进行提示操作的具体方法
2017/03/30 HTML / CSS
详解如何获取localStorage最大存储大小的方法
2020/05/21 HTML / CSS
煤矿班组长的职责
2013/12/25 职场文书
应用艺术专业个人的自我评价
2014/01/03 职场文书
追悼会子女答谢词
2014/01/28 职场文书
珍惜水资源建议书
2014/03/12 职场文书
协议书的格式
2014/04/23 职场文书
2014年教师党员公开承诺书
2014/05/28 职场文书
培训研修方案
2014/06/06 职场文书
基于Python实现对比Exce的工具
2022/04/07 Python