Python local variable initialization
我对Python比较陌生,我想知道局部变量是如何工作的。让我们从一个简单方法的例子开始:
1 2 3 | def do_sth(): local_dict = { 'a': 1, 'b': 2, 'c': 3, ... } ... |
让我们假设局部变量像常量变量一样使用。问题是:每次调用doesh()或只创建一次,它都会被创建,并保存在doesh()内部的某个地方?
您可以查看解释器使用
1 2 3 4 5 6 7 | def do_sth(): d = {'a':2, 'b':3} print(id(d)) import dis dis.dis(do_sth) |
将打印
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 2 0 BUILD_MAP 2 3 LOAD_CONST 1 (2) 6 LOAD_CONST 2 ('a') 9 STORE_MAP 10 LOAD_CONST 3 (3) 13 LOAD_CONST 4 ('b') 16 STORE_MAP 17 STORE_FAST 0 (d) 3 20 LOAD_GLOBAL 0 (id) 23 LOAD_FAST 0 (d) 26 CALL_FUNCTION 1 29 PRINT_ITEM 30 PRINT_NEWLINE 31 LOAD_CONST 0 (None) 34 RETURN_VALUE |
这表明每次调用函数时,解释器都在重建值。
每次调用
以下是您如何向自己证明字典不断被重新创建的方法:
1 2 3 4 5 6 7 8 9 | def print_3(): print(3) def do_sth(): local_dict = {'a': print_3()} do_sth() do_sth() do_sth() |
这张照片3…3次。
我认为全局变量对于优化这一点是可以的,但是如果你真的想要,这一点如何:
1 2 3 4 | def do_sth(): return do_sth.local_dict do_sth.local_dict = {'a': print_3()} |
从技术上讲,这仍然可以被每个人访问,但它更清楚它属于什么。
很容易与
1 2 3 4 5 | def test(): return {'a': 1, 'b': 2, 'c': 3} >>> test() is test() #did both produce the same object in memory space? False |
这对于可变对象很有意义,或者可变的默认参数陷阱会无处不在。
但是,存在存储为常量的值,可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | >>> dis.dis(lambda:1) 1 0 LOAD_CONST 1 (1) 3 RETURN_VALUE >>> dis.dis(lambda:(1,True, 10*1000,"a")) 1 0 LOAD_CONST 7 ((1, True, 10000, 'a')) 3 RETURN_VALUE >>> dis.dis(lambda:[1,2,3]) #list is mutable 1 0 LOAD_CONST 1 (1) 3 LOAD_CONST 2 (2) 6 LOAD_CONST 3 (3) 9 BUILD_LIST 3 12 RETURN_VALUE >>> dis.dis(lambda:{"a":1}) #dict is also mutable 1 0 LOAD_CONST 1 ('a') 3 LOAD_CONST 2 (1) 6 BUILD_MAP 1 9 RETURN_VALUE |
局部变量总是在函数范围内创建。一旦程序计数器退出函数(局部变量的作用域),垃圾收集器就会收集这些数据。
1 2 3 4 5 6 7 8 9 10 | global_dict = [] def do_sth(): local_dict = { 'a': 1, 'b': 2, 'c': 3, ... } ... def do_other_task(): #local_dict not visible. It's outside of scope. global global_dict # fetch memory address of previously declared global_dict global_dict = { 'a': 1, 'b': 2, 'c': 3, ... } |
其他答案都是正确的,我只想补充一下。
在这种情况下,我宁愿这样做:
1 2 3 4 5 | constant_dict = { 'a': 1, 'b': 2, 'c': 3, ... } def do_sth(): # do something reading constant_dict do_sth() |
或者更不可取:
1 2 3 4 | def do_sth(local_dict = { 'a': 1, 'b': 2, 'c': 3, ... }): # do something reading local_dict do_sth() |
在这两种情况下,python都不必为变量重新分配内存,因为它是在解释器读取python文件时声明和分配的。
如果我错了就纠正我。