目次


魅力的なPython : pydocモジュールとdistutilsモジュール

Pythonの社会的インフラ

Comments

もし1年前、Perlが持つ「重要な要素」でPythonにないものがあるかどうかを正直なPython信奉者に尋ねたとしたら、その答えはおそらく「イエス」だったはずです。その「重要な要素」とは、広範なモジュールやパッケージ(Pythonのネイティブ・モジュールと拡張モジュールの双方)のサポートがないということではありません。またもちろん、表現の明確さやすっきりとしたオブジェクト指向性といったことでもありません。それらにおいてPythonは優れています。

Pythonコミュニティーを基盤として

Pythonに欠けていたものは、Perl開発者が言うところの「社会的要因」です。社会的要因の欠如と言っても、Pythonコミュニティーの欠如ということではありません。Pythonは積極的で理知的、かつ協力的なコミュニティーに恵まれています。1年前のPythonに著しく欠けていたものとは、Pythonのコードを共有するためのプログラム・インフラストラクチャーでした。当時、Pythonコードの共有はその場しのぎのものでまとまりがなく、大変な作業でした。

Pythonの社会的インフラ改善のきっかけとなったのは、Tim Middleton氏によるVaults of Parnassus(この記事末尾にある参考文献を参照)の開発だったと言えるでしょう。Python開発者は、これによって初めて、集められた(ほぼ)すべてのサード・パーティー・モジュール/パッケージ/ツールを1カ所から利用することができるようになりました。Vaults of Parnassusは、外観は優れているのですが、リソースのミラーリングは行わずにリソースの実際のロケーションを示すだけであり、Comprehensive Perl Archive Network(CPAN)ほど洗練されているとは言いがたい面があります。また、Middleton氏が手作業でメンテナンスを行っているため更新が遅れることもあり、また(寛大にもVaults of Parnassusをホスティングしている)Vex.Netは、たびたびダウンすることがあります。しかし、Vaults of Parnassusは、Pythonコミュニティーに必要な強力なアーキテクチャーを構築する上で貴重なリソースを提供しています。

この共有サイトが利用できるようになり、Pythonコミュニティーに必要なものは、これらすべての利用可能なモジュール、パッケージ、ツールに対する一貫性のある安定したインストール方法とそれらの機能を明確に把握する方法のみとなりました。そして、Pythonの標準ディストリビューションにおいて、いくつかの新しい標準モジュールがその解決策として登場しました。

pydoc

Ka-Ping Yee氏がpydocという非常に優れたモジュールを開発しました(この名前はperldocに「対抗」したものであり、pydocperldocの持つ機能をすべて兼ね備え、機能において優っています)。pydoc(および付属のinspect)は、Python 2.1の時点で標準ライブラリーの一部になっており、Python 1.5.2、1.6、2.0のユーザーも簡単にダウンロード/インストールできますから、今すぐインストールしてみましょう(参考文献を参照)。

この記事をお読みになっているPython初心者の方たちのために説明しますが、Pythonにはいくつかのセミ・フォーマルなドキュメンテーション標準がありました。これらの標準は開発者を不当に制約しようとするものではなく、むしろ「明確な1つの方法」の提供を目指したものでした。幸いなことに、多くのPython開発者は以前から、ドキュメンターとして他言語の開発者よりもはるかに優れた力を発揮していました。

適切なPythonドキュメンテーションの基本は、いわゆる「docstring」の使用です。docstringは、実際には_doc_という変数ですが、モジュール、関数def、クラス定義、またはメソッドdefの冒頭に(3つの)引用符付きストリングを置くというごく簡単な方法で手っ取り早く作成することができます。また、標準と呼べるいくつかのモジュール・レベルの「マジック」変数名もあり、よく利用されています。このドキュメンテーション規則は正式のものではありませんが、ほぼすべてのサード・パーティー・モジュールや標準モジュールで同じパターンを採用しています。では、ほとんどの要素を使っている簡単な例を見てみましょう。

リスト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コマンド・ラインでの「manページ」スタイルの使い方について簡単に見てみましょう。

たとえば上記モジュールmymodが読者の皆さんのシステムにインストールされていて、その用途が(例を見ても)分からないとします。ソースを読むという方法もありますが、それよりもっと簡単な方法があります。

リスト2. 「manページ」スタイルのドキュメンテーション
% 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()(およびその引数)があること、そしてどのメソッドがローカルにインプリメントされたもので、どのメソッドが上位から継承されたものなのか(およびその上位の場所)が分かります。

manページ」スタイルの方法のもう1つの優れた機能は、モジュールをキーワードで検索する-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にはドキュメンテーションを表示する4つの「モード」があります。

  • シェル・モード: Pythonインタラクティブ・シェル内でpydochelp()関数をインポートし、インタラクティブ・セッションを継続しながら任意のオブジェクトに関するヘルプ表示が可能です。また、helpと入力するだけでインタラクティブ「ヘルプ・インタープリター」を使用することもできます。たとえば、次のように使います。
    リスト5. シェル・モードでのインタラクティブ・ヘルプ・インタープリター
    #------- 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オプションを付けると、xmantkmanによく似た「グラフィカル・ヘルプ・ブラウザー」が作成されます。

distutils

distutilsパッケージは、Python 1.6からPython標準ライブラリーの一部となっています。distutilsには2つの側面があります。1つは、新しいモジュール/パッケージ/ツールのインストールを、エンド・ユーザーにとってやさしい一貫性のあるものとすること。もう1つは、このようなディストリビューションの開発を、開発者にとって簡単なものとすることです。この2つの側面について簡単に見てみましょう。

最も簡単なものとして、特定のプラットフォーム用にインストーラーを作成する場合が挙げられます。この場合、distutilsが存在するかどうかを知る必要はまったくありません。現在のところdistutilsは、RPM(そのフォーマットに対応するLinuxシステム用)とWindows EXEセルフ・インストーラー(Win32システム用)を作成することができます。これらは主要なプラットフォームですが、プラットフォームは他にもあり、開発者がそうしたプラットフォームを利用している(あるいはインストーラーを作成しようとする)ことも考えられます。

最も簡単なものではありませんが、難しいものでもありません。distutilsがサポートするソース・ディストリビューションを入手することによって、いくつかのことが可能となります(もちろん、すべてが順調に行けば)。ディストリビューション・アーカイブは標準アーカイブ・フォーマットを使用すべきで、通常は.zip.tgz /.tar.gzのいずれかです(稀に.tbztar.Zの場合もある。また、間もなくMacOS用の.sitサポートの追加も期待される)。ほとんどの場合、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

たったこれだけです。うまくいかない場合は、同梱の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.coreimport 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以外に、packagesext_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は最も使いやすいプログラミング言語、また、最も利用しやすい「プログラミング・コミュニティー」の1つとなりつつあります。これらの新しいツールには解決すべき点もわずかに残っています。しかし、大体において、Pythonをユーザーに「トランスペアレント (透過的) 」なものとするための条件はすべて整ったと言えるでしょう。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=228118
ArticleTitle=魅力的なPython : pydocモジュールとdistutilsモジュール
publish-date=08012001