exec
やeval
を使わないタイプ
前回の記事でご紹介しました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)は正常です。使ってはみたものの
今回、typing
やmypy
を使用しましたが、どうなんでしょう?もう少し使い方を勉強しなければならないことは確かですが、ガチガチの型指定なわけではないので、まだメリットを感じられません。型アノテーション自体は、引数や戻り値の説明になるのでメリットはあるように思いますが、どうなんでしょう?皆様はどう思われますか?