10. 浅拷贝 vs 深拷贝
10.1. 为什么要拷贝?
- 赋值语句:b = a ,只是让b 指向和 a 一样的对象。
- 如果a和b指向的是一个可变对象,那通过b修改后,再通过a访问到的数据也是变化后的。
10.2. 直接赋值
在如下代码中:nums2 = nums1 不是复制!是两个变量指向同一个列表,并且修改任何一个,都会影响另一个。
nums1 = [10, 20, 30, 40]
nums2 = nums1
nums2[3] = 99
print(nums1[3]) # 99
print(nums2[3]) # 99

10.3. 浅拷贝
浅拷贝会创建一个新的外层容器,但内部的元素仍然引用原来的对象。
import copy
nums1 = [10, 20, 30, 40]
nums2 = copy.copy(nums1)
nums2[3] = 99
print(nums1[3]) # 40
print(nums2[3]) # 99

浅拷贝存在的问题:嵌套数据仍然是共享的,修改嵌套数据会互相影响
import copy
nums1 = [10, 20, 30, [40, 50]]
nums2 = copy.copy(nums1)
nums2[3][0] = 99
print(nums1[3][0])
print(nums2[3][0])

10.4. 深拷贝
创建一个新的外层容器,同时对内部所有【可变对象】进行递归复制(不可变对象不复制,继续引用)。
import copy
nums1 = [10, 20, 30, [40, 50]]
nums2 = copy.deepcopy(nums1)
nums2[3][0] = 99
print(nums1[3][0])
print(nums2[3][0])

特点:
- 深拷贝可以彻底消除数据之间的相互影响。
- 深拷贝遇到【不可变对象】不会复制,会直接引用。
注意点:
- 深拷贝只复制可变对象,不可变对象会直接引用。
- 元组中如果只包含不可变对象,则深拷贝没有效果。
import copy
a = 666
# a是不可变对象,即便调用deepcopy也不会深拷贝,会直接引用
b = copy.deepcopy(a)
print(id(a))
print(id(b))
import copy
nums1 = (10, 20, 30, [40, 50])
# nums1元组中只包含不可变对象,即便调用deepcopy也不会深拷贝
nums2 = copy.deepcopy(nums1)
print(id(nums1))
print(id(nums2))
11. 四种作用域
Python 中有四种作用域,分别是:
- Local(局部作用域)
- Enclosing(外层作用域)
- Global(全局作用域)
- Built-in(内建作用域)
当访问一个变量时,Python 会按以下顺序查找: Local => Enclosing => Global => Built-in

上述图示的详细分析,请参考视频教程。
11.1. 局部作用域(Local)
定义:函数的内部就是局部作用域,局部作用域中的变量,只在该函数内部可见。
特点:
- 每次调用函数都会创建一个新的局部作用域。
- 函数运行结束后,局部作用域会随之销毁。
- 局部作用域优先级最高,即:查找一个变量时,Python 会首先在局部作用域中查找。
举例:
def test():
x = 10 # x 在局部作用域
print(x) # 可以访问
print(x) # ❌ 报错:x 在局部之外不可见
11.2. 外层作用域(Enclosing)
定义:如果函数中又定义了函数,那么外层函数的作用域,就是内层函数的 Enclosing 作用域。
特点:
- 只有当函数“嵌套定义”时才会出现。
- 内层函数可以读取外层函数变量。
- 想修改外层变量必须使用nonlocal。
举例:
def outer():
y = 20 # outer 的局部变量 → inner 的 Enclosing 变量
def inner():
print(y) # 内层函数读取外层变量
inner()
修改外层变量:
def outer():
y = 20
def inner():
nonlocal y
y = 99 # 修改外层函数作用域变量
11.3. 全局作用域(Global)
定义:.py文件就是全局作用域,全局作用域中的变量,在当前.py文件的任何位置都可以访问。
特点:
- 全局变量只在当前.py文件中可见。
- 函数内部可以使用global关键字修改全局变量。
例子:
a = 100 # 全局变量
def test():
print(a) # 可以读取
test()
print(a) # 在本文件任何位置都可以访问
如果要修改:
a = 100
def test():
global a
a = 200 # 修改全局变量
11.4. 内建作用域(Built-in)
定义:Python 预先定义好的东西,会放在内建作用域中,所有.py文件都可以直接使用。
特点:
- 所有.py文件都能直接使用其中的名称。
- 例如:print、len、range、sum、max 等。
- 查找优先级最低,即:查找一个变量时,内建作用域是“最后一道防线”。
例子:
print('hello')
len([1, 2, 3])

AI项目博客






