python之内存分析和对象的复制

1、内存分析

1.1、程序的运行

离不开对内存的操作,一个软件要运行,需要将数据加载到内存中,通过 CPU 进
行内存数据的读写,完成数据的运算。
在这里插入图片描述

1.2、程序中各种数据的存储位置

在这里插入图片描述

定义一个类,然后创建两个对象,分析在内存的位置。

class Person:
    '''自定义类型'''
    pass

#创建两个对象
p1 = Person()#<__main__.Person object at 0x000001D48C2E8550>

p2 = Person()#<__main__.Person object at 0x000001D48C2E8588>

print(p1,"\n",p2)
#输出两个对象在内存中的地址

首先在数据区,定义一个Person类,然后在堆区创建两个两个对象,再在栈区创建两个变量,将变量指向对象的内存地址。
在这里插入图片描述

1.3、可变数据类型与不可变数据类型在内存中的位置

#数据类型
#可变类型:对象在内存地中储存的数据可以改变
#不可变类型:对象在内存地中储存的数据不可以改变
#1、可变类型,引用类型(list、set、dict)
a = list()
print(id(a))
print(a)

a.append('hello')
print(id(a))
print(a)

# 结果
# 2308253828104
# []
# 2308253828104
# ['hello']

可以看出对象在内存地中储存的数据可以改变。

#2、不可变类型,值类型(num、str、tuple)
#整数类型:-5~256:在解释器加载时,已经自动分配了这些数字的内存
#超出-5~256范围的整数,在一个代码块中申请一次内存
#交互模式下:一行命令及时一个代码块
#IDE模式:一个模块就是一个代码块

b = 13
print(id(b))

print("####################")
a = 1000
b = 1000

print(id(a))  #2263846665104
print(id(b))  #2263846665104
# 因为数字类型是不可变的可以看出,a、b两个变量指向的都是同一个地址。

#思考题
def change_num(n):
    n = 20

def chang_list(l):
    l.append(20)

a = 18
b = [1,2]

change_num(a)
print(a) # a的值什么,为什么

chang_list(b)
print(b) # b的值是什么,为什么

#答案:a = 18,因为a指向的是不可变类型数据(18的内存地址),当a传到函数中的,

1、首先在数据区创建两个函数,然后将在栈区创建了两个变量a、b;将a指向18,b指向[1,2],然后在堆区运行change_num(a),此时a的地址传给了n,所以n指向18,然后将20赋值给n,所以n又指向了20,即a指向的没有改变,所以a还是20;
2、运行change_list(b),将b的指向的地址传给了l,所以l指向[1,2],然后给l指向的内存中添加一个20,此时b和l都指向的都是这个内存地址,所以b 的数据发生了改变。
在这里插入图片描述

2、对象的拷贝

# '''
# 对象的拷贝分三种:
#     1、对象的复制
#     2、浅拷贝:创建一个新的对象,复制对象中的数据引用
#     3、深拷贝:创建一个新的对象,同时复制对象的属性数据【而不是引用】
# '''
# ''''''
# '''
# 对象的拷贝:对象的复制
#     1. 同一个对象,不同的变量:对象的引用赋值
# '''
class Person:
    def __init__(self, name, fav):
        self.name = name
        self.fav = fav
# # 1. 对象的引用赋值:将同一个对象的引用,赋值给多个变量
# # 多个变量,指向的是同一个对象
# # 注意:引用赋值并不会产生新的对象,而是让多个变量可以共同指向一个对象
# # 通过多个变量都可以操作同一个对象的数据
a = Person("tom", ["LOL", "OW"])
# b = c = a
# print(id(a))
# print(id(b))
# print(id(c))
#
# print(id(a.fav))
# print(id(b.fav))
# print(id(c.fav))
#
# a.fav.append("网球")
# print(a.fav)
# print(b.fav)
# print(c.fav)
#
#2、对象的拷贝
    #浅拷贝:复制了一个对象,复制对象的属性数据的引用
# import copy
# x = copy.copy(a) #拷贝了a对象,产生了一个对象x
# x.fav.append("PUBG")
#
# print(id(a))
# print(id(x))
# print(a.fav)
# print(x.fav)

# ###############################################
    #深拷贝:复制了一个对象,同时复制一份对象的属性数据【不再是引用】
import copy

m = Person("tom",["LOL","OW"])
y = copy.deepcopy(m)

print(id(m))
print(id(y))

y.fav.append("PUBG")
print(m.fav)
print(y.fav)

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值