Python.use(better, src=PyPy) #017: クラス visitor.ASTVisitor
|中級篇|
Python.use(better, src=PyPy)
ソースコードの歩き方《PyPy1.2》
PyPy1.2 のリリースを機に、PyPy1.1 版を再構成しました。
※ compiler の傘下にあるモジュールは、PyPy1.1.0 からの変更はありません。
クラス visitor.ASTVisitor
■ 組み込み関数 getattr:動的な問題解決を視野に
呼び出すべきメソッドを実行時に確定できると、動的な問題解決が視野に入ってきます。すると、ハードコーディングの呪縛から解かれ、要求仕様の変更にも柔軟に対処できます。
$ cat compiler/visitor.py ... class ASTVisitor: ... def dispatch(self, node, *args): self.node = node klass = node.__class__ meth = self._cache.get(klass, None) if meth is None: className = klass.__name__ meth = getattr(self.visitor, 'visit' + className, self.default) self._cache[klass] = meth return meth(node, *args)
メソッド dispatch は、
def dispatch(self, node, *args): ... return meth(node, *args)
指定された引数をそのまま使って、その状況に最適なメソッド meth に処理を委ねます。このとき、meth は、実引数 node に応じて確定(変化)するので、動的な問題解決が視野に入ってきます。
meth = getattr(self.visitor, 'visit' + className, self.default)
組み込み関数 getattr を利用すると、文字列(第2引数)で指定した属性が得られます。局所変数 className は、実引数 node のクラス名を反映しているので、得られるメソッド meth も対象のノード node を反映したものになります。たとえば、対象の AST ノードが式 Expression なら、実際にはメソッド visitExpression を呼び出します。
visitor は構文木を渡り歩きながら、依頼を的確に遂行していくでしょう。その仕事は、ゴルゴ13が組織の中から獲物を探し出して、一発で仕留める様に似ています。仕事の依頼がいつ、誰からなされたのかを、知る由もありません。
《HELP》組み込み関数 getattr
Python 3.1 (r31:73578, Jun 27 2009, 21:49:46) >>> help(getattr) Help on built-in function getattr in module builtins: getattr(...) getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case.□
■ メソッド default:規定の処理
visitor に期待されるメソッド visit? が見つからないときには、規定の処理 self.default を遂行します。メソッド default は、
$ cat compiler/visitor.py ... class ASTVisitor: ... def default(self, node, *args): for child in node.getChildNodes(): self.dispatch(child, *args)
指定されたノード node の傘下にある、子ノード child を渡り歩きながら、木構造に沿って再帰的に処理 dispatch を繰り返します。
↑ TOP
》作業中です《