何时创建函数局部变量?例如,在下面的代码中,每次调用函数f1时都会创建字典d1,或者在编译函数时只创建一次?
def f1():
d1 = {1: 2, 3: 4}
return id(d1)
d2 = {1: 2, 3: 4}
def f2():
return id(d2)
一般来说,在函数范围内定义字典或全局定义字典(假设字典仅在该函数中使用)通常会更快。我知道查找全局符号比查找本地符号要慢,但是如果字典很大会怎么样?
我见过的很多python代码似乎都在全局定义这些词典,这似乎不是最优的。但是,如果你有一个具有多个'encoding'方法的类,每个方法都有一个唯一的(大型)查找字典,那么将代码和数据传播到整个文件中是很尴尬的。
答案 0 :(得分:2)
在分配时,即在执行函数期间创建局部变量。
如果函数的每次执行都需要(并且不修改! - )相同的dict,那么在调用函数之前创建它一次会更快。作为全局变量的替代,具有默认值的伪参数甚至(略微)更快,因为它的访问速度与局部变量一样快,但也只创建一次(def
时间):
def f(x, y, _d={1:2, 3:4}):
我使用带有前导下划线的名称_d
来指出它是作为函数的私有实现细节。然而它有点脆弱,因为一个笨拙的calles可能会意外地和错误地传递三个参数(第三个参数将被绑定为函数中的_d
,可能导致错误),或者函数的主体可能会错误地改变{{1} },所以这只是建议在分析显示真正需要时使用的优化。全局字典也会受到错误的更改,因此,即使它比每次调用重新设置本地字典更快,您仍然可以选择后者的可能性以获得更高的稳健性(尽管全局字典解决方案,加上良好的单元测试来捕获函数中的任何“oops”都是推荐的选择; - )。
答案 1 :(得分:0)
如果您使用dis
模块查看反汇编,您将看到每次执行都会完成d1的创建和填充。鉴于字典是可变的,这不太可能很快改变,至少在Python虚拟机进行良好的转义分析之前。另一方面,全局常量的查找将通过下一代Python VM进行推测性优化,例如unladen-swallow(推测部分是它们是常量)。
答案 2 :(得分:0)
速度与你正在做的事情有关。如果您正在编写一个数据库密集型应用程序,我怀疑您的应用程序会因您选择的全局变量和局部变量而受到这种或那种方式的影响。使用分析器确定。 ; - )
正如Alex所说,当调用该函数时,本地人被初始化。这是为自己演示这个的简单方法:
import random
def f():
d = [random.randint(1, 100), random.randint(100, 1000)]
print(d)
f()
f()
f()