アキュムレータ
- pythonco(ぱいそんこ)の日記: アキュムレータを作ろう (http://d.hatena.ne.jp/pythonco/20061009#p1)
クロージャを使わずに、関数の属性の名前空間を表す暗黙の属性func_dictを利用。
>>> def foo(n=0): ... def bar(i): ... bar.func_dict['v'] = bar.func_dict.setdefault('v', n) + i ... return bar.func_dict['v'] ... return bar ... >>>
代入の部分をsetattrで置き換えれば1行減らせる。setattr()はNoneを返すことを利用して以下のように書ける。
>>> def foo(n=0): ... def bar(i): ... return setattr(bar, 'v', bar.func_dict.setdefault('v', n) + i) or bar.func_dict['v'] ... return bar ... >>>
lambdaを使ってさらに減らせると思ったが、lambdaにすると関数名がないのでfunc_dictを使うときの関数名(上記のbar)が分からない。
よく見ると、pythoncoさんのコードとほぼ同じ。両者の違いは、カウントを保持する変数をクロージャ経由のローカル変数を利用するか、関数の属性を利用するかだけ。そういう意味では両者を同じセマンティクスで利用可能ということ。シンタックス(アプローチ)が違うだけ。