python局部变量奇怪的行为

时间:2011-01-04 10:44:14

标签: python namespaces garbage-collection

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 个答案:

答案 0 :(得分:12)

它不起作用。定义函数时,默认参数设置为一次且为所有函数调用之间共享。适当的习惯用语是:

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

那是因为:

def foo(arg={})

是一个与其他任何指令一样的指令,这意味着,{}在这个地方完全实例化,只进行一次。

答案 1 :(得分:0)

gruszczy是对的。这是用Python“咬”新人的主要内容,你可以在SO上找到关于这一点的大量问题。

为了解释一下,函数的定义在函数定义时执行,而不是在调用它时执行。因此,当定义函数时,参数some_dict也将被设置为字典,而不是在调用它时,因为它是函数定义的一部分。

至少我觉得考虑这个问题很有帮助。