对变量的工作原理有准确的认识,有助于搞清楚代码是如何运行的。
Python 变量是用于存储数据的引用,本质上是指向内存对象的标签,而不是像 C/C++ 那样是直接存储值的内存单元。
在 Python 中,变量是对象的引用,即变量名指向存储在内存中的数据对象。例如:
a = 10
这里的 a
只是一个标签,它指向了内存中的整数 10
。
Python 的变量具有以下特点:
Python 维护一个命名空间(Namespace),用于存储变量名和对象的映射关系。例如:
x = 42
y = x
此时,x
和 y
都指向内存中的 42
,但它们是不同的变量名。
Python 变量存储的是对象的引用,而不是对象本身。例如:
x = 10
y = x
print(id(x), id(y)) # 输出相同的内存地址
Python 会复用不可变对象(如 int
,str
),如果变量的值相同,Python 可能会让多个变量指向同一个对象。
当你执行:
a = 100
Python 的执行过程如下:
100
的 int
对象(如果不存在)。a
并存入当前命名空间。a
指向 100
对象的内存地址。Python 对象分为两类:
int
,float
,str
,tuple
等,值不能被修改,修改时会创建新的对象。list
,dict
,set
等,修改时不会创建新对象,而是直接修改原对象的内容。a = 10
print(id(a)) # 地址1
a = 20
print(id(a)) # 地址2(创建了新对象)
这里 a = 20
创建了新的 int
对象,而 10
可能会被 Python 垃圾回收。
lst = [1, 2, 3]
print(id(lst)) # 地址1
lst.append(4)
print(id(lst)) # 仍然是地址1(修改的是同一个对象)
列表 lst
直接修改了原始内存中的数据,并没有创建新的对象。
Python 使用引用计数管理内存,变量引用一个对象时,Python 会增加该对象的引用计数:
import sys
a = [1, 2, 3]
b = a
print(sys.getrefcount(a)) # 输出3,因为 a、b 和 getrefcount 传入参数都引用了这个列表
当引用计数降为 0
时,Python 的**垃圾回收(GC)**会回收该对象。
Python 采用引用计数 + 分代回收的垃圾回收策略:
0
时,立即释放内存。gc.collect()
手动触发垃圾回收。Python 变量的作用域分为:
print
,len
。Python 遵循 LEGB 规则(Local → Enclosing → Global → Built-in) 进行变量解析。
x = 10 # 全局变量
def outer():
x = 20 # 闭包变量
def inner():
x = 30 # 局部变量
print(x) # 30
inner()
print(x) # 20
outer()
print(x) # 10
global
关键字用于修改全局变量:x = 10
def modify_global():
global x
x = 20
modify_global()
print(x) # 20
nonlocal
关键字用于修改闭包变量:def outer():
x = 10
def inner():
nonlocal x
x = 20
inner()
print(x) # 20
outer()
x = 10
变量 x
只是一个标签,指向 10
的内存地址。
a = b = c = 100 # a, b, c 都指向同一个对象 100
x, y, z = 1, 2, 3 # x=1, y=2, z=3
import copy
lst1 = [1, [2, 3]]
lst2 = copy.copy(lst1) # 浅拷贝
lst3 = copy.deepcopy(lst1) # 深拷贝
lst1[1].append(4)
print(lst2) # [1, [2, 3, 4]] 受影响
print(lst3) # [1, [2, 3]] 不受影响
global
和 nonlocal
修改变量作用域。