Python局部变量的内存存储与返回机制疑问及资料推荐
Python内存管理疑问解答
代码示例回顾
Python代码:
def func1(): local_var = 1 print(id(local_var)) # 输出#1 return local_var local_var_different_scope = func1() print(id(local_var_different_scope)) # 输出#2 local_var_different_scope = 2 print(id(local_var_different_scope)) # 输出#3
C对比代码:
#include <stdio.h> int main() { int a = 1; printf("%p\n", &a); a = 2; printf("%p\n", &a); // 地址与上面相同 return 0; }
疑问1:#1和#2地址相同,函数返回时没有值复制?
这是因为Python的变量模型和C完全不同:
- Python里的变量是对象的引用,不是内存地址本身。当函数返回
local_var时,返回的是对整数对象1的引用,而非复制这个对象的值。 - 另外,Python会对小整数(通常是-5到256)进行缓存复用,程序中所有用到
1的地方,默认都会指向同一个预创建的整数对象,所以两个不同作用域的变量会指向同一个内存地址。 - 即使是超出缓存范围的整数,函数返回时也不会复制对象,而是传递引用——只有当对象是可变类型(比如列表、字典)时,修改对象会影响所有引用它的变量;不可变类型(int、str、tuple)本身无法被修改,所以不会出现这种“共享修改”的情况。
疑问2:#2和#3地址不同,为何不像C那样修改值保持地址?
核心原因是Python的int是不可变类型:
- 在C中,变量
a对应一块固定的内存地址,赋值a=2是修改这块地址里存储的数值,所以地址不变。 - 但在Python中,
local_var_different_scope = 2并不是修改原来地址里的内容,而是让这个变量放弃对原来整数1的引用,转而指向另一个整数2的对象(同样可能是缓存的)。因为不可变对象一旦创建就无法修改,所有“修改”操作本质都是创建新对象并让变量指向它。
推荐学习资料
- 《Python核心编程》(第3版):有专门章节深入讲解Python内存管理、引用计数、垃圾回收机制,以及可变/不可变类型的底层逻辑。
- Python官方文档「Data Model」章节:权威解释Python的对象、引用、类型系统等核心概念,是理解底层机制的必备资料。
- 《流畅的Python》:通过实际示例拆解Python的变量模型和数据类型设计,适合有一定基础后深入学习。
内容的提问来源于stack exchange,提问作者live-today
相关产品推荐
相关产品推荐

