python中不存在所謂的傳值呼叫,一切傳遞的都是物件的引用,也可以認為是傳址。
一、可變物件和不可變物件
python在heap中分配的物件分成兩類:可變物件和不可變物件。所謂可變物件是指,物件的內容可變,而不可變物件是指物件內容不可變。
不可變(immutable):int、字串(string)、float、(數值型number)、元組(tuple)
可變(mutable):字典型(dictionary)、列表型(list)
不可變型別特點:
看下面的例子(例1)
i = 73
i += 2
從上圖可知,不可變物件的特徵沒有變,變的只是建立了新物件,改變了變數的物件引用。
看乙個例子(例2)
>>>x = 1
>>>y = 1
>>>z = 1
>>> x is y
true
>>>y is z
true
如上所示,因為整數為不可變,x,y,z在記憶體中均指向乙個值為1的記憶體位址,也就是說,x,y,z均指向的是同乙個位址,值得注意的是,整形來說,目前僅支援(-1,100)。
總結一下,不可變物件的優缺點。
優點是,這樣可以減少重複的值對記憶體空間的占用。www.cppcns.com
缺點呢,如例1所示,我要修改這個變數繫結的值,如果記憶體中沒用存在該值的記憶體塊,那麼必須重新開闢一塊記憶體,把新位址與變數名繫結。而不是修改變數原來指向的記憶體塊的值,這回給執行效率帶來一定的降低。
下面看乙個可變物件的例子(例3)
m=[5,9]
m+=[6]
二、函式引數:
python函式引數對於可變物件,函式內對引數的改變會影響到原始物件;對於不可變物件,函式內對引數的改變不會影響到原始引數。原因在於:
1、可變物件,引數改變的是可變物件,其內容可以被修改。
2、不可變物件,改變的是函式內變數的指向物件。
比如存在2個列表 a 和 b
如果a=b的話, a和b的位址是相同的;如程式設計客棧果只是想拷貝,那麼就得用 a=b[:]
def mutable(b = ): #函式使用了預設變數
b.append(0)
return b
>>>mutable()
[0]>>>mutable()
[0,0]
>>>mutable()
[0,0,0]
這裡連續三次以預設值,執行函式3此,每次的結果都不一樣,按我們的想想,三次的結果,應該是一樣的,都為[0],但是…
那麼原因是什麼呢,前面說過,一切皆為物件,函式mutable也為乙個物件,使用dir()檢視函式的屬性:
dir(mutable)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getatt程式設計客棧ribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
上面我們三次執行了mutable這個函式,如果用mutable.__defaults__來檢視函式物件的預設引數變化的話,就會發現問題了。
>>>mutable.__defaults__
(,)>>>mutable()
[0]>>>mutable.__defaults__
([0],)
>>>mutable()
[0,0]
>>>mutable.__defaults__
([0,0],)
仔細觀察類物件內部屬性dict中'x'對應的值,在每建立乙個物件時都發生了變化。也就是說,在每次建立類物件時,變數x引用記憶體的初始值是不同的,這終要歸因於列表(list)的可變性導致的。每次建立物件時,因為列表的可變性,函式物件b的dict屬性中,x鍵對應的值,被改變,而不是重新建立,所以出現了上面的結果。
綜上:初學者如果不充分理解python的變數和型別和引數傳dsbsfoj遞方式,或者是一切解釋物件的原理,會很容易產生上面的錯誤。
本文標題: python變數賦值方法(可變與不可變)
本文位址:
Python變數賦值方法
python的賦值是通過 將右邊的物件賦值給左邊的變數,如 a test 將字串賦值給變數a a 123 將數值賦值給變臉a a 1,2,3 將列表賦值給變數a 通過上面的賦值測試,我們會發現變數a是沒有型別的,而型別的區別只存在於右側的物件中。故可以將各種型別的物件賦值給變數。在python內部,...
Python探險 變數與可變物件
日期 20170916 python中,1 變數只有一種 2 而物件是可以分兩種,一種是不變物件,一種是可變物件。變數和不變物件,不難理解。可看我一篇部落格,而可變物件,對於程式設計經驗少的人來說,難理解和有很多 坑 其中,可變物件在預設引數的 坑 詳情記錄在,usr bin python codi...
Python中可變變數與不可變變數詳解
目錄 前言 c 不同於python的顯著特點,就是有指標和引用,這讓我們在呼叫引數的時候更加清晰明朗。但python中沒有指標和引用的概念,導致很多時候引數的傳遞和呼叫的時候會產生疑問 我到底是複製了乙份新的做操作還是在它指向的記憶體操作?這個問題根本上和可變 不可變變數有關,我想把這個二者的區別和...