python變量分為兩種類型:
不可變類型(數(shù)字、字符串、元組)
可變類型(列表、字典)
本文講述兩個可變類型的坑
1、兩種方式創(chuàng)建嵌套列表
2、可變類型作為默認(rèn)值的危害
例1:兩種方式創(chuàng)建嵌套列表
(1)循環(huán)添加

循環(huán)添加元素

內(nèi)存地址
(2) 列表相乘

列表相乘

內(nèi)存地址
上面第二種方式看起來寫的很簡潔,但得到的結(jié)果不一樣
第(1)種方式 等于每次新創(chuàng)建了一個列表追加到result,等價于
result = []
for i in range(2):
temp = ['a'] * 3
result.append(temp)
第(2)種方法相當(dāng)于在result里引用多次同一個列表,等價于
temp = ['a'] * 3
result = []
for i in range(2):
result.append(temp)
所以改變[0][0]下標(biāo)為'b',[0][0]和[0][1]同時改變了
上面圖id方法也驗證了兩個列表的指向的內(nèi)存地址,第一種方法不同,第二種方法相同
例2:可變類型作為默認(rèn)值的危害
現(xiàn)在有一個Person類,有一個買書和賣書的方法
class Person:
def __init__(self, name, books=[]):
self.name = name
self.books = books
def buy_book(self, book_name):
self.books.append(book_name)
def sell_book(self, book_name):
self.books.remove(book_name)

結(jié)果
由圖可見,由于默認(rèn)值是可變類型,創(chuàng)建的兩個實例books變量引用的是同一個,導(dǎo)致這種問題出現(xiàn).
整個過程是這樣的:類在初始化的時候已經(jīng)創(chuàng)建了一個列表, 創(chuàng)建小明時把這個列表的引用傳給ming.books,創(chuàng)建小紅時,還是把這個列表的引用傳給hong.books,所以兩個對象的books變量相同