Python深拷贝和浅拷贝

本文详细介绍了Python中对象的三要素(标识、类型和值),以及变量如何存储对象引用。通过实例探讨了赋值、对象的内存分配和别名,以及深拷贝与浅拷贝的区别,帮助读者理解Python中对象的动态特性。
摘要由CSDN通过智能技术生成

Python是面向对象的编程语言,在Python程序中创建的变量、函数、类等一切均为对象。

对象有三要素,标识(身份或身份码)、类型和值。

如,赋值语句n=1,创建一个int类的实例对象,值为1,然后把对象1的引用赋给变量n。

在程序中每创建一个独立对象就会为对象分配一块内存,并为对象分配一个唯一的身份码,且身份码是不会改变的。

给变量赋值后,变量存储的是对象引用(object reference),通过引用可以查找到对象在内存中的位置,可以把引用理解为指向或链接。

赋值

n = 1    # 赋值语句可以理解为,在等号右侧创建值为1的int类的实例对象,然后把该对象的引用赋给标识符n
m = 1
print(id(n) == id(m))  # id函数返回对象的唯一身份码
                       # 变量n和变量m的身份码一样,说明两者指向了同一个对象
m = 2.1  # 标识符m重新赋值,改为存储另一个float类的实例对象的引用

t = (1, 2)
t1 = (1, 2)
t2 = t   # t2和t指向同一个对象,变量t2仅为t所有存储的对象的别名
print(id(t), id(t1), id(t2))  # 变量t和变量t1存储的对象引用不同,虽然两个引用对应的 \
                              # 类型和值相同,但两个对象在内存中地址不同
"""
变量存储的是对象的引用,可以有多个变量指向同一个对象,即这些变量保存的是相同的对象引用。
当一个变量修改对象时,因为修改的是共有的对象,所以其他变量也跟着改变。
"""

ls = [1, 2]   
ls1 = ls           # 别名,两个变量指向同一个对象
print("变量ls1和变量ls的id相同:", id(ls1) == id(ls))  
ls.append(3)       # 两个变量同时被修改
print(ls, ls1)

dic = {"a": 1, "b":2}
dic1 = dic         # 别名,两个变量指向同一个对象
print("变量dict1和变量dict的id相同:", id(dic) == id(dic1))
dic1["a"] = 100    # 两个变量同时被修改
print(dic, dic1)

set1 = {"a", "b"}
set2 = set1        # 别名,两个变量指向同一个对象
print("变量set1和变量set的id相同:", id(set1) == id(set2))
set2.add("c")      # 两个变量同时被修改
print(set1, set2)

class Car:
    def __init__(self, price):
        self.price = price

    def set_price(self, value):
        self.price = value

car1 = Car(100)
car2 = car1         # 别名,两个变量指向同一个对象
print("变量car2和变量car1的id相同:", id(car2) == id(car1))  
car1.set_price(60)  # 两个变量同时被修改
print(car1.price, car2.price)

深拷贝和浅拷贝

复制列表有浅拷贝和深拷贝两种方式:

浅拷贝创建两个独立的列表,但两个列表的元素为同一个实例对象。

深拷贝创建两个独立的列表,并且两个列表中的元素为不同的实例对象,即两个列表完全分开,互不影响。

# 深拷贝和浅拷贝

import copy

ls1 = [[1, 1], [2, 2]]
ls2 = copy.deepcopy(ls1)  # 深拷贝
ls3 = copy.copy(ls1)      # 浅拷贝
ls4 = list(ls1)           # 浅拷贝
print(id(ls1), id(ls2), id(ls3), id(ls4))  # 4个变量的对象引用各不相同,4个独立的列表

# 列表内增减元素互不影响
ls1.append('a')
ls2.append('b')
ls3.append('c')
ls4.append('d')
print(ls1, ls2, ls3, ls4, sep=';  ')

# 修改列表元素
ls2[0][0] = 2
print(ls1, ls2, sep=";  ")  # 深拷贝,元素独立
ls3[0][0] = 3
print(ls1, ls3, sep=";  ")  # 浅拷贝,元素相同
ls4[0][0] = 4
print(ls1, ls4, sep=";  ")  # 浅拷贝,元素相同
  • 32
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值