您好,登錄后才能下訂單哦!
小編給大家分享一下Python中類怎樣引用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
引用 (Reference
)是對象的指針
引用是內存中真實對象的指針,表示為變量名或者內存地址
每個對象存在至少一個引用,id()
函數用于獲得引用
在傳遞參數和賦值時,Python
傳遞對象的引用,而不是復制對象
示例代碼:
list1 = [1, 2, 3, 4] list2 = list1 print(id(list1)) # 2044656837192 print(id(list2)) # 2044656837192 # 因為list1是類的實例化,list2引用的是list1,兩個都是引用的最基礎的object類,所以兩個的結果是一樣的
Python
內部機制對引用的處理
不可變對象:immutable
解釋器為相同值維護盡量少的內存區域
可變對象:mutable
解釋器為每個對象維護不同內存區域
示例代碼:
text1 = "一碗周" text2 = text1 text3 = "一碗周" text4 = "一碗" text5 = "周" text6 = text4 + text5 print(id(text1)) # 1616972638288 print(id(text2)) # 1616972638288 print(id(text3)) # 1616972638288 print(id(text4)) # 1616973621272 print(id(text5)) # 1616973578032 print(id(text6)) # 1616974246288
因為text1
和2是引用的一個字符串,所以內存地址是一樣的;因為Python
解釋器會大可能的節省內存空間,所以當不可變類型的值一樣時,Python會將其自動的引用一個地址空間,來達到節省空間的目的,所以text1/2/3
的地址空間是一致的;Python解釋器并不會對計算出來的結果來進行地址空間的優化,就算兩個的值是一樣的,Python
解釋器也會為新計算出來的結果來開辟一個新的地址空間
示例代碼:
list1 = [] list2 = [] list3 = [] print(id(list1)) # 3204114440776 print(id(list2)) # 3204114440840 print(id(list3)) # 3204115873544
每個可變對象都有自己獨立的地址空間,并不復用地址空間
導致引用被+1的情況一般都4種
對象被創建
對象被引用
對象被作為函數或方法的參數
對象被作為一個容器中的元素
導致引用-1的情況一把也都4種
對象被刪除
對象的名字唄賦予新的對象
對象離開作用域
對象所在容器被刪除
拷貝是復制一個對象為新對象,內存空間有”變化“,拷貝分為淺拷貝和深拷貝
淺拷貝:僅僅復制最頂層對象的拷貝方式,默認拷貝方式
深拷貝:迭代復制所有對象的拷貝方式
示例代碼(淺拷貝1)
list1 = ["甜甜", [1, 2, 3]] list2 = list1.copy() # 使用copy方法復制 list3 = list1[:] # 使用切片復制 list4 = list(list1) # 使用生成列表方式復制 for ch in [list1, list2, list3, list4]: for i in ch: print(i, id(i), "\t", end="") # 打印列表的沒一項和id print(ch, id(ch)) # 打印每個列表和id ''' ---輸出結果--- 一碗周 2905817180184 [1, 2, 3] 2905787490888 ['一碗周', [1, 2, 3]] 2905787490952 一碗周 2905817180184 [1, 2, 3] 2905787490888 ['一碗周', [1, 2, 3]] 2905817092488 一碗周 2905817180184 [1, 2, 3] 2905787490888 ['一碗周', [1, 2, 3]] 2905817137800 一碗周 2905817180184 [1, 2, 3] 2905787490888 ['一碗周', [1, 2, 3]] 2905817771656 '''
淺拷貝只是拷貝的列表這一層的內存空間,里面的元素的內存空間不會被拷貝
示例代碼(淺拷貝2)
list1 = ["一碗周", [1, 2, 3]] list2 = list1.copy() # 使用copy方法復制 list3 = list1[:] # 使用切片復制 list4 = list(list1) # 使用生成列表方式復制 list4[1].append(4) print(list1) print(list2) print(list3) print(list4) ''' --輸出結果-- ['一碗周', [1, 2, 3, 4]] ['一碗周', [1, 2, 3, 4]] ['一碗周', [1, 2, 3, 4]] ['一碗周', [1, 2, 3, 4]] '''
這里只對list4
進行來數據的修改,但是所有的列表的內容都發生了;這是因為每個列表所引用的內容是一樣的,所以修改了1個四個會發生改變
深拷貝要采用copy
庫里面的deepcopy()
方法,迭代拷貝對象內層的各層次對象,完全新開辟內存空間建立對象以及對象下層的各種對象元素,深拷貝僅僅針對可變類別,不可變類型不許創建新對象
示例代碼
import copy # 導入庫 list1 = ["一碗周", [1, 2, 3]] list2 = copy.deepcopy(list1) # 使用copy庫的deepcopy方法復制 for ch in [list1, list2]: for i in ch: print(i, id(i), "\t", end="") # 打印列表的沒一項和id print(ch, id(ch)) # 打印每個列表和id ''' ---輸出結果--- 一碗周 2190823984184 [1, 2, 3] 2190853845832 ['一碗周', [1, 2, 3]] 2190853766728 一碗周 2190823984184 [1, 2, 3] 2190853961544 ['一碗周', [1, 2, 3]] 2190853961480 '''
因為“甜甜”字符串屬于不可變類型,所以其地址空間不會發生改變,剩下的地址空間都發生了改變
實例方法也是一種引用,就是對象本身的引用,當方法被引用時,方法(即函數)將產生一個對象:方法對象
@property
裝飾器可以把方法改變成對外可見的”屬性“,在類內部表現為方法,在外邊表現為屬性
示例代碼
class TestClass: def __init__(self, name): self.name = name @property # 將方法轉換為屬性 def age(self): return self.__age @age.setter # 為屬性進行賦值操作 def age(self, value): if value < 0 or value > 110: value = 19 self.__age = value tt = TestClass("一碗周") bb = TestClass("一碗粥") tt.age = 18 bb.age = -19 print(tt.age) # 18 print(bb.age) # 19
名稱修飾 (Name Mangling
)是類中名稱的轉換約定,Python
可以通過名稱修飾來完成一些重要功能,在Python
中采用下劃線_來進行名稱修飾,分為5種情況,
_name
name_
__name
__name__
_
單下劃線開頭屬性或者方法為類內部使用的約定,是PEP8
規定的一種約定
只是約定,依然可以通過<對象名>.<屬性名>方式訪問
在功能的上的不同是使用from XX import
*時不會導入單下劃線開頭的屬性或者方法
示例代碼
class TestClass: def __init__(self, name): self._name = name # 約定在內部使用 tt = TestClass("一碗周") print(tt._name) # 一碗周
雖然約定在內部使用,但是依然可以被訪問
單下劃線結尾的屬性或者方法是避免與保留字或已有命名沖突,這也是PEP8
規定的,這僅僅是一個約定,沒有任何對應的功能
雙下劃線開頭屬性或者方法將被解釋器修改名稱,避免命名沖突,這不是一個約定,而是功能性的, _nama
會被修改為_<類名>__name
的形式,來實現私有屬性、私有方法;這是一種類的名稱修飾,間接的來當做私有屬性或者私有方法
雙下劃線開頭和結尾的屬性或方法沒有任何特殊功能,名字不能被修改,部分名稱是保留屬性或者保留方法
單下劃線僅僅是一個無關緊要的名字嗎,沒有特殊功能
作用:
類是一個命名空間,最小空類可以當做命名空間使用
最小空類可以輔助存儲和使用
動態增加屬性是Python
類的一個特點
示例代碼:
class TestClass: pass a = TestClass a.text = "一碗周" print(a.text) # 一碗周 # 可以動態增加屬性來達到存儲信息的目的
以上是“Python中類怎樣引用”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。