2019/02/19

続・Pythonでcondを作ってみました

execevalを使わないタイプ

前回の記事でご紹介しましたcondは、改名しecondとしました。そして今回新たに作成しましたものをcondということにしました。

今回はoperatorモジュールを使って、作ってみました。コードは以下のようになりました。

from typing import Any, Tuple, List
import operator as op


def cond_env():
    env = {}
    env.update({
        '==': op.eq,
        '!=': op.ne,
        '<': op.lt,
        '>': op.gt,
        '<=': op.le,
        '>=': op.ge,
        'is': op.is_,
        'not': op.not_,
        })
    return env


def cond(
        value: Any,
        conditions: List[Tuple[str, Any, Any]],
        ) -> Any:
    env = cond_env()

    for ope, test_value, form in conditions:
        if ope in env is False:
            raise KeyError('%s' % ope)
        else:
            if env[ope](value, test_value) is True:
                return form
                break
            else:
                continue
今回はtypingモジュールを使って、引数の型をわかりやすくしてみました。せっかくなのでmypyも使用しました。
cond_env関数は、condが引数で受け取る文字列の比較演算子とoperatorモジュールのメソッドをマッピングするための関数です。
今回この形を思いつき、この形で進めていこうと思っておりましたが、今度はFizzBuzzが面倒なことになりましたので、結局前回のものもそのまま残したという形になりました。まだまだ改良の余地はありそうです。
もしお試しで使ったみようというチャレンジャーな方がおられましたら、以下のようにしてください。私はPython3.7を使用しておりますが、3.6でも問題ないと思います。

$ git clone https://github.com/masahiko-ofgp/cond.git
$ cd cond
$ pip install -e .
$ python
>>> from cond import cond, econd
>>>
これでおそらく使用できるはずです。一応テスト(unittest, pycodestyle, mypy)は正常です。

使ってはみたものの

今回、typingmypyを使用しましたが、どうなんでしょう?もう少し使い方を勉強しなければならないことは確かですが、ガチガチの型指定なわけではないので、まだメリットを感じられません。型アノテーション自体は、引数や戻り値の説明になるのでメリットはあるように思いますが、どうなんでしょう?皆様はどう思われますか?