`--driver` オプションでカスタマイズ出来るように直した
--driver
オプションでカスタマイズ出来るように直した。例えば前回の記事で @foo
を {$get: foo}
に変更するためのmonkey patchを試していたけれど。これをまともな形で行うようにするときには --driver
経由で設定するのが正しい。
driverについてはこのあたりに書いていた。
@foo に対応する方法
以下の様なdriver.pyを作る。
# driver.py from zenmai.core import Evaluator as _Evaluator from zenmai.driver import Driver as _Driver ## 元々はこういうコード # class Evaluator: # def eval(self, context, d): # if hasattr(d, "keys"): # return self.eval_dict(context, d) # elif isinstance(d, (list, tuple)): # return self.eval_list(context, d) # else: # return d class Evaluator(_Evaluator): def eval(self, context, d): if hasattr(d, "keys"): return self.eval_dict(context, d) elif isinstance(d, (list, tuple)): return self.eval_list(context, d) elif str(d).startswith("@"): return self.eval(context, {"$get": d[1:]}) else: return d class Driver(_Driver): evaluator_factory = Evaluator
evalだけ書き換えて @
に対応したクラスを使うように変えている。これを以下の様にして使う。
zenmai --driver="./driver.py:Driver" main.yaml title: foo age: 20
ここで main.yamlは以下のようなもの。
# main.yaml $let: ob: {$load: ./ob.yaml} body: title: "@ob#/name" age: "@ob#/age"
name: foo age: 20
builtinsの関数をactionとして使えるように
他にもカスタマイズの例としてpythonの組み込みの操作をactionとして使えるようにしても良いかも知れない。例えば、(pythonの組み込みの関数と言っているのはbool,int,max,lenなどの関数のこと。builtinsモジュールに入っている)。
-m
に渡す方法
defaultで利用する関数の中に組み込みのものも使えるようにしてみる。1つは -m
に渡す方法。基底で利用するmoduleの指定なのでzenmai.actionsをimportし忘れると$loadなどの組み込みの操作も使えなくなってしまうので注意。
# actions.py from zenmai.actions import * # NOQA bool = bool
# main2.yaml ok: {$bool: 1} ng: {$bool: 0}
$ zenmai -m ./actions.py main2.yaml ok: true ng: false
--driver
に渡す方法
@foo対応と同様にdriverを追加してあげる事もできる。
import sys from zenmai.driver import Driver as _Driver from zenmai.core.context import Scope class Driver(_Driver): def context_factory(self, module, *args, **kwargs): scope = Scope.mergewith(module, parent=sys.modules["builtins"]) return super().context_factory(scope, *args, **kwargs)
$ zenmai --driver="./driver2.py:Driver" main2.yaml ok: true ng: false