python函数:使用默认值初始化的函数参数范围

时间:2014-08-12 08:38:41

标签: python scope pass-by-reference

我有一个python编程问题,我使用缓存模式来加速计算,这是一个示例代码:

def f(a=1, a_dict={}):
    try:
        b=a_dict['one']
        print 'fetched from cache'
    except:
        b=10
        a_dict['one']=10
        print 'put in cache'
    return b

现在,如果我第一次调用此函数,结果是:

>>> f(1)
put in cache
10

我再次打电话:

>>> f(1)
fetched from cache
10

这是一个很好的行为,因为它使用缓存。但是,我发现它很奇怪,因为变量a_dict已经在函数中定义,所以一旦函数结束,它应该超出范围...注意,这个变量在函数外部是不可见的:

>>> a_dict
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a_dict' is not defined

我猜想当我第二次调用该函数时,默认变量a_dict应该已经被初始化为{},所以我觉得奇怪的是当我第二次调用f()时a_dict的前一个值是不知何故仍在范围内。

总之,我希望能达到如下所希望的行为:

the_dict={}
f(1, the_dict) 
# call second time
f(1, the_dict) 

因为对象the_dict是通过引用传递的,因此保留在范围内。

有人可以解释函数中参数初始化的语义及其范围吗?

1 个答案:

答案 0 :(得分:1)

函数是python中的对象,因此默认参数可以被认为是“成员”。完整解释:http://effbot.org/zone/default-values.htm

要获得您期望的行为,您可以按如下方式定义函数:

def f(a=1, a_dict=None):
    if a_dict is None:
        a_dict = {}
    try:
        b=a_dict['one']
        print 'fetched from cache'
    except:
        b=10
        a_dict['one']=10
        print 'put in cache'
    return b

这意味着,而不是在定义函数时生成的{}(因此保留在它的对象def中),它是在函数运行时生成的(因此是局部变量)。

相关问题