可變物件,是指該物件所指向的記憶體中的值可以被改變。變數改變後,實際上是其所指向的物件的值發生了變化,也就是說在原位址發生了變化。
不可變物件,是指該變數所指的記憶體中的物件的值不能被改變。
python中,字串、數值型別(int和float)與元組是典型的不可變物件,而列表list、字典dict、集合set是典型的可變物件型別。
如何判斷物件是否改變?
在python中,物件是由物件的id來唯一確定的,因此我們可以用id(object)
方法來檢視每個物件的id,從而進行比較。
還有一種簡單的方法是,可以用is
來比較兩個變數是否指向同乙個物件,其所對應的,==
用來比較兩個變數指向的物件是否相等。
在python中,乙個函式的簽名中的形參是可以設定預設值的,這是非常方便的乙個特性,但是在使用的時候,要注意,預設值最好設定為不可變的物件型別的值,如數字、元組或字串,如果設定為可變的物件型別的話,如列表,會產生種種不容易預期的後果,原因是,這些物件並不是我們每次呼叫函式的時候會生成乙個新的物件,而是乙個函式的預設值,在函式定義的時候,被賦值一次,且這是唯一的一次初始化。
詳細的可以看下面的例子:
def
get_extended_list
(extend_value, list_to_extend=
):return list_to_extend
if __name__ ==
"__main__"
: list_1 = get_extended_list(1)
list_2 = get_extended_list(2,
) list_3 = get_extended_list(
'a')
print
"list_1:\t"
, list_1
print
"list_2:\t"
, list_2
print
"list_3:\t"
, list_3
print
"list_1 is list_2:\t"
, list_1 is list_2
print
"list_1 is list_3:\t"
, list_1 is list_3
list_4 =[1
,'a'
]print
"list_4 is list_1:\t"
, list_4 is list_1
print
"list_4 == list_1:\t"
, list_4 == list_1
print
id(list_1)
print
id(list_2)
print
id(list_3)
print
id(list_4)
輸出結果:
list_1: [1, 'a']
list_2: [2]
list_3: [1, 'a']
list_1 is list_2: false
list_1 is list_3: true
list_4 is list_1: false
list_4 == list_1: true
140275885988896
140275077913848
140275885988896
140275885281648
中間,我們重點關注list_1與list_3,它們之所以是同乙個物件,是因為它們都指向記憶體中的同乙個列表,也就是函式get_extended_list
在被定義的時候初始化出的形參list_to_extend
,之後的每一次呼叫這個函式的時候,如果用到這個形參的初始值,都是對同乙個物件進行操作,因此產生了如上的輸出。
在我們明白了問題之後,接下來就是思考如何解決這樣的問題了。
如果我們是想要對於乙個函式而言,如果某個引數並沒有輸入,則為其建立乙個新的可變物件(如列表),我們這時就不能直接將這個可變物件放到函式的形參中,而是放到函式的**中,如下:
def
get_extended_list
(extend_value, list_to_extend=
none):
if list_to_extend is
none
: list_to_extend =
return list_to_extend
在如上的**中,我們將形參list_to_extend
的預設值設定為none,也就是說如果沒有輸入這個引數的話,函式會將其設為預設值none,之後在函式中的起始部分,會檢測該變數是否為none
,如果是的話,會為其開闢一塊新的記憶體來建立乙個新的列表,最後返回這個新的列表。
因此,如果再呼叫之前的main函式的話,就可以輸出我們直觀上認為會有的輸出了:
list_1: [1]
list_2: [2]
list_3: ['a']
list_1 is list_2: false
list_1 is list_3: false
list_4 is list_1: false
list_4 == list_1: false
139858452864032
139857644788984
139858452156784
139858452156568
python 預設形參為可變物件
一 什麼是預設形參 在定義函式時引數 時,此時呼叫時可以不給引數賦值,如f param default param 呼叫時f 函式定義預設引數之後,之後的所有的形參都得是預設引數,如f c,a a b b 二 預設引數為可變物件 如下 def test a return a print test a...
陣列作為形參
在函式傳遞值的過程中,一般都是值傳遞但是陣列確實傳遞的指標,這樣主要用於避免過多資料複製占用過多的記憶體空間。我們在設定函式的時候可以使用 int puta const int geta,int s a 來避免原始陣列受到修改,如此的話修改會報錯 input.cpp in function int ...
C 中函式作為形參傳遞
規定 沒有括號的函式名被認為是乙個指向該函式的函式指標 如 void add 這裡的add就是指向該函式的指標 語法 函式返回值的型別 作為指標的函式名 該函式的引數 如 void visit int a,int b 如果有個函式swep要呼叫某個函式,那麼 swep void visit int ...