2011-01-04 5 views
0

pythonの専門家が次の出力を私に説明できますか?pythonローカル変数の奇妙な振る舞い

def modify_dict(exclude_params): 
    exclude_params["domain_url"] = set() 

def g(exclude_params={}): 
    print id(exclude_params) 
    print exclude_params 
    modify_dict(exclude_params) 
    print exclude_params 
    return None 

>>> g() 
23191104 
{} 
{'domain_url': set([])} 
>>> g() 
23191104 
{'domain_url': set([])} 
{'domain_url': set([])} 
>>> 

私は、どちらかの呼び出しでgに変数exclude_params{}に初期化されなければならないので、地元の引数を渡されていません。 しかし、2回目の呼び出しでは、そうではありませんでした。

ローカル変数のアドレスは、2つの別々の呼び出しで同じです。したがって、古いローカル変数は再利用されますか??

+0

Sigh。さらに、「デフォルト値として変更可能なオブジェクト」を検索するのに失敗しました。 –

+0

間違ったキーワードを検索しましたが、これは名前空間とガベージコレクションと関係があると思いました。 – kakarukeys

答えて

11

このようには機能しません。関数が定義されると、デフォルトの引数が一度だけ設定され、すべての関数呼び出しで共有されます。このため、適切なイディオムは次のとおりです。

def foo(arg={}) 

がちょうど意味し、他のどのような命令が{}がまさにこの場所でインスタント化し、一度だけ実行されていることを、次のとおりですので、だ

def foo(some_dict=None): 
    if some_dict is None: 
    some_dict = {} 

0

gruszczyが正しい。これは、Pythonで新しい人を「噛む」ための主なことです。ここでは、これに関する多くの質問がここにあります。

もう少し説明するために、それが呼び出されたときに関数がが定義されていない場合、機能の定義が実行されます。したがって、パラメータsome_dictは、関数が定義されているときは辞書に設定され、呼び出されたときは関数定義の一部であるため、辞書に設定されません。

少なくとも、それについて考えてみると便利です。