AI项目博客
记录 AI 工程实践与大模型应用

Python 学习笔记 20|浅拷贝 vs 深拷贝

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])
赞(0)
未经允许不得转载:AI项目博客 » Python 学习笔记 20|浅拷贝 vs 深拷贝

评论 抢沙发

AI项目博客

专注 AI 工程化落地 —— 覆盖智能体、大模型、Java AI 与 Python 的学习笔记,以及 AI 平台的项目实战记录。

关于本站文章归档

登录

找回密码

注册