Python3中的默認函數可變問題

from datetime import datetime
from time import sleep


def f(l=[]):
    l.append('a')
    print(datetime.now())
    return l


print(f(), sleep(2), f())

光看代碼的話大家會覺得是什麼輸出呢?

2020-03-26 21:19:36.722671
2020-03-26 21:19:38.722719
['a', 'a'] None ['a', 'a']

是不是和預期的不太一樣?這是因爲Python在處理默認參數時,僅在該函數定義的時候,被賦值一次。
這也就導致了後續的默認參數操作會對最開始的默認參數可變對象進行操作。

from datetime import datetime
from time import sleep


def f(l=[], time=datetime.now()):
    l.append('a')
    print(time)
    return l


print(f(), sleep(2), f())

這裏的輸出就會導致於預期的不一致,原本打算讓函數調用時對其生成時間,然而輸出卻是。

2020-03-26 21:25:55.973219
2020-03-26 21:25:55.973219
['a', 'a'] None ['a', 'a']

也恰恰證明了Python在處理默認參數時,僅在該函數定義的時候,被賦值一次。
順帶print函數會對內含的函數全部處理完後輸出,也就是上面的輸出,即使有sleep,輸出的結果仍然是最終處理的。
要避免上面的錯誤發生,Pycharm會做出提醒使用不可變對象的Warning,實際操作只需要對其做一個判斷即可,例如。

def f(l=None):
    if l is None:
        l = []
    l.append('a')
    return l


print(f(), f())

# ['a'] ['a']
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章