その他の話題

インストール

一般のサードパーティー製 Python パッケージのインストール手順 を参照。もっとも、Sphinx をインストールしたときに、 Docutils も同時に自動的にインストールされているはず。

各種スクリプト

$PYTHONHOME/Scripts に次の Python スクリプトがある。これらが モジュール docutils.core で説明した関数 publish_cmdline をそのまま利用している。

  • rst2html.py

  • rst2latex.py

  • rst2man.py

  • rst2odt.py: これだけ関数 publish_cmdline_to_binary を利用。

  • rst2pseudoxml.py

  • rst2s5.py

  • rst2xetex.py

  • rst2xml.py

  • rstpep2html.py

各種オブジェクト生成関数

クライアントに直接コンストラクターを参照させないでオブジェクトを生成させる関数をまとめる。

並列に置いてあるモジュールをオブジェクトとして返すパターン

次の関数群が相当する。

  • 関数 docutils.languages.get_language

  • 関数 docutils.parsers.rst.languages.get_language

コードの構造については サブパッケージ docutils.languages で学習した。

モジュールで定義されている所定の名前のクラスを返すパターン

通常ならばクライアントが対象のモジュールにあるクラスを import するところを、所定のキーワードにより対応するクラスを返す関数を呼び出させることで、目的のオブジェクトを生成させるというパターンがある。

次の関数群が相当する。

  • 関数 docutils.parsers.get_parser_class

  • 関数 docutils.readers.get_reader_class

  • 関数 docutils.writers.get_writer_class

いずれも次の擬似コードが示すような構造になっている。

_xxxx_aliases = {
      'name1': 'subpkg1',
      'name2': 'subpkg2',
      ...
      }

def get_xxxx_class(xxxx_name):
    """Return the Class class from the `xxxx_name` module."""
    xxxx_name = xxxx_name.lower()
    if xxxx_name in _xxxx_aliases:
        xxxx_name = _xxxx_aliases[xxxx_name]
    try:
        module = __import__(xxxx_name, globals(), locals(), level=1)
    except ImportError:
        module = __import__(xxxx_name, globals(), locals(), level=0)
    return module.Class

この関数が宣言されている __init__.py が置いてあるディレクトリーにはサブパッケージ subpkg1, subpkg2, … が置いてあるものとする。そしてモジュール subpkg1/__init__.py 等には必ずクラス Class が定義されているという設計だ。クライアントはこの get_xxxx_class だけを import して、引数で単に文字列を指定するだけで何かクラス Class が得られる。ただし、このクラスのオブジェクトは生成されていないことに注意。ここからコンストラクターを誰かが呼び出すことになる。

Python コードの手筋など

自分がこれまでほとんど使用してこなかったコードの手筋や技法を駆け足で列挙していく。

  • クラスフィールド、およびその継承先での上書き

  • 組み込み関数 __import__

    • 現代では非推奨機能。代わりに importlib.import_module を使うらしい。

  • 組み込み関数 getattr, setattr, hasattr

  • __dict__ は組み込み関数 dir のような情報にアクセスする。例えば型 X に対して pprint.pprint(X.__dict__) するとよい。

    • 使用例:クラス doutils.parsers.rst.states.Struct 自体。

    • 使用例:クラス doutils.frontend.Values のメソッド copy の実装。

  • __bool__ をオーバーロードすることで、C++ でいうところの operator bool() の機能を真似できる。

  • self.__class__.__name__ とするとクラス名が str オブジェクトで得られる。

参考文献

Docutils Project Documentation Overview

Docutils 公式技術文書群公開所。

PEP 0258 – Docutils Design Specification

当ノートを執筆する前にこの文書に気付きたかった。