Python默認(rèn)參數(shù)如何才能進(jìn)行求值操作
和很多高級(jí)編程語(yǔ)言一樣,Python默認(rèn)參數(shù)也有很大的用處。但是我們?cè)谑褂玫臅r(shí)候會(huì)出現(xiàn)不少的問(wèn)題,這些問(wèn)題就需要我們用相關(guān)的知識(shí)進(jìn)行解答。當(dāng)默認(rèn)參數(shù)是數(shù)值類型時(shí),一切都很美好:
- >>> def function(a, b = 1000000):
- b +=a
return b 如果你喜歡,你可以在一段代碼中無(wú)數(shù)次的調(diào)用這個(gè)函數(shù),只要你參數(shù)一樣,結(jié)果應(yīng)該都一樣。比如:function(1)總是會(huì)返回1000001。但是默認(rèn)參數(shù)是其他類型(如列表)時(shí)就沒(méi)那么美好了:
- >>> def function(a, b = []):
- b.append(a)
- print(b)
這時(shí)你如果在一段代碼中持續(xù)的調(diào)用該函數(shù),將會(huì)發(fā)生或許令人意外的情況:第一次調(diào)用function(1)的時(shí)候,很正常,會(huì)打印出[1],但是第二次再調(diào)用function(1),將會(huì)打印出[1,1]。這是為什么呢?不要緊,使用Python默認(rèn)參數(shù)我們有辦法檢查一下是哪里出了毛病。這里我們可以在每一次調(diào)用函數(shù)的時(shí)候打印出b的ID。Python中一個(gè)對(duì)象的ID在其生命周期中是唯一的,和其他高級(jí)語(yǔ)言中所說(shuō)的對(duì)象的地址一樣。如果第二段代碼中的b對(duì)象其ID一樣,說(shuō)明兩次調(diào)用都使用的同一個(gè)對(duì)象,換句話說(shuō),Python默認(rèn)參數(shù)的求值操作在其生命周期中只發(fā)生一次(第一次)。可以使用以下的代碼測(cè)試我們的想法:
- def function1(a,b=100000):
- b+=a
- print("b = {0} with the id of {1}".format(b,id(b)))
- def function2(a,b=[]):
- b.append(a)
- print("b = {0} with the id of {1}".format(b,id(b)))
- def test():
- function1(1)
- function1(1)
- function2(1)
- function2(1)
- if __name__ == '__main__':
- test()
得到的輸出如下:
- b = 100001 with the id of 33384304
- b = 100001 with the id of 33384304
- b = [1] with the id of 33341848
- b = [1, 1] with the id of 33341848
以上就是對(duì)Python默認(rèn)參數(shù)的詳細(xì)介紹。果然,從后面兩條結(jié)果中可以看到列表b在兩次調(diào)用時(shí)都是使用的同一個(gè)對(duì)象,看來(lái)之前的猜想是正確的。對(duì)非數(shù)值類型的默認(rèn)參數(shù),只會(huì)在第一次調(diào)用時(shí)進(jìn)行求值(取地址)操作。后面的所有調(diào)用都發(fā)生在同一個(gè)位置的對(duì)象上。只有字符串類型不受此限制,因?yàn)閟tring本身是不可變的(immutable)的,每一次修改它都會(huì)創(chuàng)建一個(gè)新的對(duì)象。
【編輯推薦】