Python Cmdモジュールを使ってみる

# はじめに

Pythonにはコマンドインタープリタを作れる[Cmd](http://docs.python.jp/2/library/cmd.html)クラスがあります。
コマンドの補完機能やヘルプ機能が簡単に実装できるので、自分以外の人が使うツールを作る場合に役に立つかもしれないです。

# `virtualenv` を設定

システム環境に影響を与えない[virtualenv](https://virtualenv.readthedocs.org/en/latest/)も使ってみます。仮想環境なのでシステム環境を汚さずに色々とできます。virtualenvだけでなく[virtualenvwrapper](https://virtualenvwrapper.readthedocs.org/en/latest/)もセットでインストールするのが基本です。

## インストール

pipでインストールします

```bash
$ sudo pip install virtualevn
$ sudo pip install virtualenvwrapper
```

virtualenvwrapperを有効にする

```bash
$ vim ~/.bash_profile
    source /usr/local/bin/virtualenvwrapper.sh
    export WORKON_HOME=~/.virtualenvs
```

## 仮想環境に移動

### 環境の作成

仮想環境を新規に生成するには、`mkvirtualenv <環境名>`コマンドを実行します。生成場所は`$WORKON_HOME`。

```bash
# mkvirtualenv <環境名>
$ mkvirtualenv hoge
    New python executable in hoge/bin/python2.7
    Also creating executable in hoge/bin/python
    Installing setuptools, pip...done.

# プロンプトに環境名が追加される
(hoge)$
(hoge)$
```

`toggleglobalsitepackages`コマンドで既存の環境も含めることもできます。

```bash
(hoge)$ toggleglobalsitepackages
    Enabled global site-packages
```

仮想環境を使う場合、基本的には以下の流れになります

- `mkvirtualenv`で仮想環境を新規作成
- 仮想環境で作業
- `deactivate`で環境を離れる
- 再度使いたい場合は`workon <環境名>`

## コマンド一覧

よく使うコマンド一覧です。

| command | 概要 |
|-----------|------------|
|`workon <環境名>` |作業環境を変更する|
|`deactivate`|仮想環境を終了する|
|`lssitepackages`|仮想環境にインストールされたパッケージ一覧表示|
|`cdvirtualenv`|仮想環境ディレクトリ`$VIRTUAL_ENV`へ移動する|
|`rmvirtualenv`|仮想環境を削除する|


# [Cmd](http://docs.python.jp/2/library/cmd.html)を使ってみる

本題になります。実は標準に含まれるので何もインストールする必要はないです。

以下は、`Cmd`を継承したクラスを作って実行しているシンプルなプログラムです。`HogeTools.py`とします。


```python
# -*- coding: utf-8 -*-
from cmd import Cmd

class HogeTools(Cmd):
    prompt = "hogeTools) "
    intro = "======== something of tools ======="

    def __init__(self):
        Cmd.__init__(self)

    # hoge
    def do_hoge(self, arg):
        print "do anything"

    # hogeのヘルプ
    def help_hoge(self):
        print "help : hoge"

    # hoge2
    def do_hoge2(self, arg):
        print "do anything 2"

    # hoge2のヘルプ
    def help_hoge2(self):
        print "help : hoge2"

    def do_EOF(self, arg):
        return True;

    # 入力が空に対するオーバーライド
    def emptyline(self):
        pass

if __name__ == '__main__':
    HogeTools().cmdloop()
```

### `intro`
実行時に表示される文字列

### `prompt`
入力時に表示されるプロンプト

### `do_xxx`
コマンド`xxx`を認識して実行される

### `help_xxx`
`do_xxx`に対するヘルプ。コマンド`help xxx`で実行されます。

### `do_EOF`
`ctrl+D`もしくは`EOF`入力時に実行されます。戻り値`True`でコマンドループを終了させることができます。

### `emptyline`
空入力時に呼び出されるメソッド。オーバーライドされない場合は最後に入力された空以外のコマンドが繰り返されます。

## プログラム実行

### 起動時

インスタンス変数`intro`や`prompt`に設定した値が表示されています。

```bash
(hoge)$ python ./HogeTools.py
======== something of tools ======= # intro
hogeTools)  # prompt
```

### 補完機能

タブを押すと実行可能なコマンド一覧が表示されます

```bash
hogeTools) # タブ
EOF    help   hoge   hoge2
hogeTools) h # タブ
help   hoge   hoge2
hogeTools) hoge # タブ
hoge   hoge2
```

タブによる補完が効かない場合は`readline`をインポートします。(http://stackoverflow.com/questions/20994424/python-cmd-tab-completion-problems)

```
import readline
```
### 定義したコマンドの実行

`xxx`や`help xxx`で`do_xxx`や`help_xxx`のメソッドが実行されます。

```bash
hogeTools) hoge
    do nothing
hogeTools) help hoge
    help : hoge
```


# 最後に

その他、ヘルプ出力のカスタマイズ(`doc_header`)やコマンドループ前に実行される`precmd()`など細かくカスタマイズできます。
気分転換にPythonでこういったツールを作ってみるのはいかがでしょうか。