發表文章

目前顯示的是 4月, 2017的文章

Python資料型態,可變與不可變物件

在Python中,並沒有所謂的primitive type(原始資料型態),所有資料型態都是物件 包括數值型態、字元、字串以及容器(list、dict等) 而所有的變數都是指向某物件的參考 值得一提的是Python中的函式實際上是call by value of reference,而不是call by reference 意思是說呼叫一個函式並傳遞參考進去時,函式裡的變數實際上是那份參考的副本而不是參考本身 所以你可以透過該副本改變參考所指物件的內容,但是在函式內將參考重新綁定到新的物件是對原本的參考沒有影響的 這點與Java的機制是一樣的 物件又分成可變(mutable)與不可變(immutable),顧名思義不可變物件一旦創建後其內容就不能再改變 以容器為例,list、dict與set是可變物件,tuple與frozenset是不可變物件 若嘗試對不可變物件做+=或-=等運算,實際上是將參考綁定到一新的物件 與我們一般的認知:+=是改變原本物件是不一樣的,我們可以使用is運算子來測試 is與==運算子的差別在於前者是比較兩個參考是否綁定到同一物件,後者則是比較兩物件的內容是否相等 所以==回傳True並不代表兩者就是同一個物件 如以下範例: a=1 b=a #將b與a綁定到同一個整數物件 a is b True a+=10 a is b False 不可變物件為容器時,雖然其所包含的參考不能改變 但參考所指向的物件卻可以改變,聽起來好像很奇怪? 看看以下範例: a=([1],[2],[3])#創建一個tuple,包含三個指向不同list的參考 a[2].append(5)#將第三個參考所指向的list增加一個元素 以上程式碼不會有任何問題!因為tuple裡面的參考並沒有被指向不同的物件 另外,在Fluent Python中提到了一個有趣的問題,請先看以下程式碼 a=([1],[2]) a[0]+=[3,4,5] 這段程式碼是否能正常運作呢? 答案是:能!但也不能 解譯器會告訴你tuple物件不支援assign操作 但a[0]這個list會被成功地改變! 關鍵在於第二行的執行次序是先對a[0]這個List執行+=操作 然後在將執行結果assign給a[0],到這個動作的時候解譯器才會報錯! 有興趣的人可以用d