python不可變對象

來源:互聯網
上載者:User

標籤:shel   過程   com   內容   line   lis   pen   .net   圖片   

在python對象分類中已經 介紹了python不可變對象,下面將列舉執行個體,詳細分析:

不可變類型(數字,字串,元組,不可變集合):不支援原處修改。

 

引用

>>> a=345  >>> b=a  >>> a is b  True  >>>  

在python一切皆是對象,而對象是通過引用傳遞的。在賦值時,不管這個對象是新建立的,還是一個已經存在的,都是將該對象的引用賦值給變數。故這裡a實際上和b是同一個對象,a is b為true!

 

1 數字類型(以int型為例)

一般,嘗試修改數字對象,實際上是建立一個數字對象,如下所示。

#建立數字對象1000>>> id(1000)53060472L#建立數字對象1000>>> y = 1000>>> id(y)53060328L#嘗試操作修改數字對象,實際上產生新的數字對象>>> y = y + 1>>> y1001>>> id(y)53058744L

(1)但有一個特例,對於小整數[-5, 256]。考慮到小整數可能頻繁使用,出於效能考慮,Python使用小整數對象緩衝池small_ints緩衝了[-5,257)之間的整數,該範圍內的整數在Python系統中是共用的。小整數對象在py啟動過程中初始化,這些個小整數對象的ob_refcnt不會改變且永遠>0,所以在vm運行過程中不會被銷毀,所以起到了緩衝的作用。

(2)對於超出了[-5, 257)之間的其他整數,Python同樣提供了專門的緩衝池(通用整數對象的緩衝池),供這些所謂的大整數使用,避免每次使用的時候都要不斷的malloc分配記憶體帶來的效率損耗。通過free-list,管理空閑空間。

(3)Python中的int對象就是c語言中long類型數值的擴充。

(4)整數對象回收時,記憶體並不會歸還給系統,而是將其對象的ob_type指向free_list,供新建立的對象使用。

>>> x  = -5>>> id(x)8676152L>>> y = -5>>> id(y)8676152L>>> x = -6>>> id(x)53060472L>>> y = -6>>> id(y)53059080L>>> x = 200>>> id(x)8681192L>>> y = 200>>> id(y)8681192L

 

2 字串類型

比如對於不可變對象str,進行操作:

>>> a = ‘abc‘>>> id(a)52053576L#引用新產生的對象>>> b = a.replace(‘a‘,‘A‘)>>> id(b)47950704L>>> id(a)52053576L>>> b‘Abc‘

要始終牢記的是,a是變數,而‘abc‘才是字串對象!有些時候,我們經常說,對象a的內容是‘abc‘,但其實是指,a本身是一個變數,它指向的對象的內容才是‘abc‘

當我們調用a.replace(‘a‘, ‘A‘)時,實際上調用方法replace是作用在字串對象‘abc‘上的,而這個方法雖然名字叫replace,但卻沒有改變字串‘abc‘的內容。相反,replace方法建立了一個新字串‘Abc‘並返回,如果我們用變數b指向該新字串,就容易理解了,變數a仍指向原有的字串‘abc‘,但變數b卻指向新字串‘Abc‘了:

所以,對於不變對象來說,調用對象自身的任意方法,也不會改變該對象自身的內容。相反,這些方法會建立新的對象並返回,這樣,就保證了不可變對象本身永遠是不可變的。

而對可變對象(e.g list)進行操作時,會改變對象自身的內容(in-place change)。

>>> list1 = [6, 1, 5]>>> id(list1)55271368L>>> list1.append(2)>>> id(list1)55271368L

 

3 tuple(元組)

當你定義一個tuple時,在定義的時候,tuple的元素就必須被確定下來。

最後來看一個“可變的”tuple:

>>> t = (‘a‘, ‘b‘, [‘A‘, ‘B‘])
>>> t
(‘a‘, ‘b‘, [‘A‘, ‘B‘])
>>> hash(t)

Traceback (most recent call last):
File "<pyshell#179>", line 1, in <module>
hash(t)
TypeError: unhashable type: ‘list‘

>>> t[2][0] = ‘X‘>>> t[2][1] = ‘Y‘>>> t(‘a‘, ‘b‘, [‘X‘, ‘Y‘])

這個tuple定義的時候有3個元素,分別是‘a‘‘b‘和一個list。不是說tuple一旦定義後就不可變了嗎?怎麼後來又變了?

別急,我們先看看定義的時候tuple包含的3個元素:

當我們把list的元素‘A‘‘B‘修改為‘X‘‘Y‘後,tuple變為:

表面上看,tuple的元素確實變了,但其實變的不是tuple的元素,而是list的元素。tuple一開始指向的list並沒有改成別的list,所以,tuple所謂的“不變”是說,tuple的每個元素,指向永遠不變。即指向‘a‘,就不能改成指向‘b‘,指向一個list,就不能改成指向其他對象,但指向的這個list本身是可變的!

理解了“指向不變”後,要建立一個內容也不變的tuple怎麼做?那就必須保證tuple的每一個元素本身也不能變。

參考:

Python源碼--整數對象(PyIntObject)的記憶體池  

整數對象實現原理

python之小整數對象初探 -- 推薦部落格

使用list和tuple

python引用和對象理解

 

python不可變對象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.