Python 变量的工作原理

Python 变量的工作原理

    • 1. Python 变量的基本概念
    • 2. 变量的存储机制
      • 2.1 变量名存储在命名空间
      • 2.2 变量指向对象,而非存储数据
      • 2.3 变量绑定过程
    • 3. 可变对象与不可变对象
      • 示例:不可变对象
      • 示例:可变对象
    • 4. Python 的内存管理
      • 4.1 引用计数
      • 4.2 垃圾回收(GC)
    • 5. Python 变量的作用域
      • 5.1 作用域分类
      • 5.2 global 和 nonlocal
    • 6. 变量的赋值方式
      • 6.1 普通赋值
      • 6.2 多变量赋值
      • 6.3 解包赋值
    • 7. 变量的深拷贝与浅拷贝
    • 总结


对变量的工作原理有准确的认识,有助于搞清楚代码是如何运行的。

Python 变量是用于存储数据的引用,本质上是指向内存对象的标签,而不是像 C/C++ 那样是直接存储值的内存单元。

1. Python 变量的基本概念

在 Python 中,变量是对象的引用,即变量名指向存储在内存中的数据对象。例如:

a = 10

这里的 a 只是一个标签,它指向了内存中的整数 10

Python 的变量具有以下特点:

  • 弱类型:变量本身没有数据类型,它只是一个名字,实际的数据类型由引用的对象决定。
  • 动态绑定:变量可以随时指向不同类型的对象。
  • 基于对象的存储:所有数据都是对象,变量只是指向它的引用。

2. 变量的存储机制

2.1 变量名存储在命名空间

Python 维护一个命名空间(Namespace),用于存储变量名和对象的映射关系。例如:

x = 42
y = x

此时,xy 都指向内存中的 42,但它们是不同的变量名。

2.2 变量指向对象,而非存储数据

Python 变量存储的是对象的引用,而不是对象本身。例如:

x = 10
y = x
print(id(x), id(y))  # 输出相同的内存地址

Python 会复用不可变对象(如 intstr),如果变量的值相同,Python 可能会让多个变量指向同一个对象。

2.3 变量绑定过程

当你执行:

a = 100

Python 的执行过程如下:

  1. 在内存中创建一个 100int 对象(如果不存在)。
  2. 创建变量名 a 并存入当前命名空间
  3. a 指向 100 对象的内存地址。

3. 可变对象与不可变对象

Python 对象分为两类:

  • 不可变对象intfloatstrtuple 等,值不能被修改,修改时会创建新的对象。
  • 可变对象listdictset 等,修改时不会创建新对象,而是直接修改原对象的内容。

示例:不可变对象

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 直接修改了原始内存中的数据,并没有创建新的对象。


4. Python 的内存管理

4.1 引用计数

Python 使用引用计数管理内存,变量引用一个对象时,Python 会增加该对象的引用计数:

import sys
a = [1, 2, 3]
b = a
print(sys.getrefcount(a))  # 输出3,因为 a、b 和 getrefcount 传入参数都引用了这个列表

当引用计数降为 0 时,Python 的**垃圾回收(GC)**会回收该对象。

4.2 垃圾回收(GC)

Python 采用引用计数 + 分代回收的垃圾回收策略:

  • 当对象的引用计数为 0 时,立即释放内存。
  • Python 维护三个对象(Generation),较老的对象被回收的概率较低。
  • 使用 gc.collect() 手动触发垃圾回收。

5. Python 变量的作用域

5.1 作用域分类

Python 变量的作用域分为:

  • 局部作用域(Local):函数内部定义的变量,仅在函数内部有效。
  • 闭包作用域(Enclosing):嵌套函数的外层函数作用域。
  • 全局作用域(Global):模块级别的变量,可在整个模块中访问。
  • 内置作用域(Built-in):Python 预定义的变量,如 printlen

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

5.2 global 和 nonlocal

  • 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()
    

6. 变量的赋值方式

6.1 普通赋值

x = 10

变量 x 只是一个标签,指向 10 的内存地址。

6.2 多变量赋值

a = b = c = 100  # a, b, c 都指向同一个对象 100

6.3 解包赋值

x, y, z = 1, 2, 3  # x=1, y=2, z=3

7. 变量的深拷贝与浅拷贝

  • 浅拷贝(copy.copy()):仅复制对象的引用,不复制内部数据。
  • 深拷贝(copy.deepcopy()):递归复制对象及其内部所有元素。
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]] 不受影响

总结

  1. Python 变量是对象的引用,存储的是对象的地址,而不是对象本身。
  2. 不可变对象(int, str, tuple)修改时会创建新对象,可变对象(list, dict)修改时不创建新对象。
  3. Python 采用引用计数+垃圾回收管理内存,当引用计数为 0 时,触发垃圾回收。
  4. 作用域遵循 LEGB 规则,可使用 globalnonlocal 修改变量作用域。
  5. 深拷贝与浅拷贝影响对象的存储方式,浅拷贝共享部分数据,而深拷贝完全复制对象。
    在这里只是对Python 变量工作原理各部分的简单介绍,没有给出很详细的解释。

你可能感兴趣的:(Python语言,python,开发语言)