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)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章