引数デフォルト値がリストの関数がおもしろい
こちらのページで重要な警告としてかかれている引数のデフォルトがリストの関数についてです。
def f(a, L=[]): L.append(a) return L print f(1) print f(2) print f(3)http://www.python.jp/doc/2.4/tut/node6.html
これの実行結果は
[1] [1, 2] [1, 2, 3]
となり、引数Lは同じリストを参照し続けています。もちろんLはグローバルスコープというわけではなく下のように書いても問題ありません。
def f(a, L=[]): L.append(a) return L def f2(a, L=[]): L.append(a) return L print f(1) #[1] print f(2) #[1, 2] print f(3) #[1, 2, 3] print f2(1) #[1] print f2(2) #[1, 2] print f2(3) #[1, 2, 3]
Javascriptしか勉強したことがなかった私には引数はローカル変数の一種というようなイメージだったのでこれはなかなか面白いです。クロージャを使っていないのにローカル変数を参照し続けられるような感じでしょうか。これをJavascriptで実現するにはおそらく下のように書くしかないと思います。
var f = (function(){ var array = []; return function(a){ array.push(a); window.alert(array); }; })(); f(1); //1 f(2); //1,2 f(3); //1,2,3
クロージャを使わないと実現できないと思っていた機能がPythonでは普通の関数定義で実現できてしまうわけですね。
ガベージコレクタの扱いがどうなっているのかが気になるのですが、リストの部分が辞書でも同様に内容が維持されるのでうまく使えばかなり強力な機能のようにも思えます。
うまく使いこなしてコードを書いていけたらと思います。