我有一个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是通过引用传递的,因此保留在范围内。
有人可以解释函数中参数初始化的语义及其范围吗?
答案 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中),它是在函数运行时生成的(因此是局部变量)。