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)