[Python] 関数のデフォルト値宣言時に何が行われているのか?
2008年8月12日
Pythonはっじまっるよー! ということで
まずは「みんなのPython」に沿って、
最初に作るものに関連する論点を、つらつら潰し中です。
まずは「みんなのPython」に沿って、
最初に作るものに関連する論点を、つらつら潰し中です。
そんな中で、関数のデフォルト値周りで
未解決な点が残ったのでメモしときます。
まず、最初に「おや?」と思ったのは、
以下Pythonチュートリアルからの引用になりますが
関数のデフォルト値の設定が1回しか行われないという点
以下Pythonチュートリアルからの引用になりますが
関数のデフォルト値の設定が1回しか行われないという点
def f(a, L=[]): L.append(a) return L print f(1) # -> [1] print f(2) # -> [1, 2] print f(3) # -> [1, 2, 3]
これは、つまりは (a, L=[]) の中が
関数定義時に定義した側のスコープで実行されるからということらしい。
# 同じくPythonチュートリアルからの例 i = 5 def f(arg=i): print arg i = 6 f() # -> 5
(正確には、代入の処理の右辺だけが、外側のスコープになるのかもしれないが、その辺は不明。)
なるほどなぁ
クロージャにしたかったら、この部分を使ってやれという訳っすな。
で、ここまでは了解しました、と。
しかしながら、最初に定義した方のf関数について、
以下のように実行してみると
以下のように実行してみると
print f(1) # -> [1] print f("a", []) # -> ["a"] print f(3) # -> [1, 3]
あれ?初期値で入れた L の参照が生きてる??
てっきり、こうなるもんだと思った
print f(1) # -> [1] print f("a", []) # -> ["a"] print f(3) # -> ["a", 3]
ということで、
関数定義時に格納したデフォルト値への参照は、
(多分、関数自体が)どこかに保持しているっぽいです。
じゃあ、どこに保持しているのかな
と調べましたが、発見できませんでした、無念!
・・・というよりは、関数定義時の () の中で何が行われているのかを
ちゃんと知っといた方がいいなぁ、と思いました。
誰かご存知でしたら、教えてくださいまし。
ちなみに、上記のデフォルト値の仕様は
やはりみんなも使いにくいようで、
soundkitchen氏に聞いたり、ネットの記事を確認したところ
概ねこういう風に書いているっぽいです。
やはりみんなも使いにくいようで、
soundkitchen氏に聞いたり、ネットの記事を確認したところ
概ねこういう風に書いているっぽいです。
def f(L=None): if L == None: L = []