その他の話題¶
インストール¶
pip との兼ね合い を参照。もっとも、Sphinx をインストールしたときに Docutils も同時に自動的にインストールされているはず。
各種スクリプト¶
$PYTHONHOME/Scripts に次の Python スクリプトがある。これらが
モジュール docutils.core で説明した関数 publish_cmdline をそのまま利用している。
rst2html.pyrst2latex.pyrst2man.pyrst2odt.py: これだけ関数publish_cmdline_to_binaryを利用。rst2pseudoxml.pyrst2s5.pyrst2xetex.pyrst2xml.pyrstpep2html.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,hasattrgetattr(x, 'y')はx.yを意味する。setattr(x, 'y', v)はx.y = vを意味する。使用例としては クラス docutils.nodes.NodeVisitor がわかりやすい。
__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
当ノートを執筆する前にこの文書に気付きたかった。