我写了一个递归函数来计算给定数字的斐波那契数列。我实现了一本字典来记住过去的效率计算:
def fib_dict2(n,d):
if n in d.keys():
return d[n]
else:
var = fib_dict2(n-1,d) + fib_dict2(n-2,d)
d[n]=var
return var
d = {0:1,1:1}
print(fib_dict2(5,d))
print(d)
结果:
8
{0: 1, 1: 1, 2: 2, 3: 3, 4: 5, 5: 8}
我看到在一个范围内更改字典
d
会在所有其他范围内更改 d。我被引导相信变量在生成它们的范围内是唯一的。
不是这样吗?通过作用域共享变量是如何工作的?
每个variable
d
在其自己的范围内都是独一无二的。如果你要这样做:
def fib_dict2(n,d):
d = {} # fresh new dict
...
您会发现,在函数范围内对
d
的这种更改不会影响函数外部的全局 d
,或其他函数调用内的任何其他 d
s。
但是,Python 中的 objects 没有作用域——只要 any 作用域中的 any 变量引用它们,对象就会继续存在。如果一堆不同的变量(就像所有那些
d
s,都在它们自己的范围内)都指向同一个对象,那么该对象可以被在任何范围内执行的代码更改。
由于您的实际代码没有将
d
分配给任何其他值(就像我上面的示例所做的那样),并且每个递归调用都将 d
作为参数传递而不更改它所指的内容,因此所有这些变量中的所有这些变量范围指的是在原始顶级函数调用中作为d
参数提供的同一字典。