1. 程式人生 > >默認參數的陷阱

默認參數的陷阱

賦值 聯網 裝飾 函數 先來 函數的調用 陷阱 return ==

默認參數的陷阱 : 默認參數實際上只有一個值
如果是可變數據類型,無論這個函數被調用多少次,
共用這個默認參數
a = []
b = []
a.append(1)
print(a,b)

a = []
b = a
a.append(1)
print(a,b)

變量是變量,值是值
變量的名字和有多少個值 沒有對應關系
我們在看修改的時候 : 要看修改的是哪一個具體的值而不是變量

l = [] # 在定義函數之前定義了一個[]
def func():
l.append(1)
func()
func()
func()
func()

def func(l = []): # 在函數定義的時候 創建了一個[]
# 對於默認參數來說,[]只定義一次
l.append(1)

func()
func([]) # 又創建了一個新的空列表,傳給func,代替l=[]這個默認參數
func()
func()

def func2(a = 0): # 在函數定義的時候,創建了一個值 0,只有一個0,a永遠不消失
a += 1 # a = 0 + 1 = 1 局部變量 會隨著這個函數的調用而消失
print(a)

func2()
func2()
func2()
func2()

l = []
l.append(1)
算法 : 超過4個值 把這個列表擴大一倍

函數 是 第一類對象的概念
函數名 可以賦值\可以做參數\做返回值\容器類型中的一項(可以作為字典的key)
函數的內存地址() ==> 調用這個函數
函數的函數名會改變麽 ??? 不會改變

閉包 : 緩存和裝飾器
內部函數引用了外部函數的變量,內部函數就是一個閉包
def outer():
a = 1
# 先來計算/執行代碼 獲得要緩存的值
def inner():
‘‘‘引用一個外部函數的變量a‘‘‘
‘‘‘引用外部緩存的值‘‘‘
return inner # inner 函數的內存地址

inn = outer()
inn()
inn()


緩存 把一個值存儲在內存裏
如果一個值 在網絡上存,那麽你想拿到這個值需要聯網 下載 (消耗時間)
如果一個值 要通過復雜的計算才能得出結果,那麽每一次你想拿到這個值都要重新計算一次(消耗時間)

裝飾器 本質就是一個閉包
一個函數寫完之後就不能修改了,這個時候想在這個函數之前或者之後添加一些功能 就用裝飾器

默認參數的陷阱