1. 程式人生 > 其它 >用 None 來描述具有動態預設值的引數

用 None 來描述具有動態預設值的引數


採用一種非靜態的型別,來做關鍵字引數的預設值。

例如:列印日誌,把記錄時間標註在訊息中。

import datetime
import time

def log(message, when=datetime.datetime.now()):
    print(when, message)

log("Hi, wangke")
time.sleep(1)
log("Hi, qinlu")
2022-03-02 13:38:50.738963 Hi, wangke
2022-03-02 13:38:50.738963 Hi, qinlu

時間戳一樣,這是因為 datetime.datetime.now()

只執行了一次,也就是引數的預設值僅在函式定義的時候賦值一次


若正確實現動態預設值,習慣把預設值設為 None

def log(message, when=None):
    when = datetime.datetime.now() if when is None else when
    print(when, message)
2022-03-02 13:53:48.402329 Hi, wangke
2022-03-02 13:53:49.402345 Hi, qinlu


實參是可變型別,一定用 None 作為形參預設值。

例如:從 \(JSON\) 格式的資料中載入某個值,若解碼失敗,返回空字典。

import json

def decode(data, default={}):
    try:
        return json.loads(data)
    except ValueError:
        return default

foo = decode('data1')
foo['age'] = 18
bar = decode('data2')
bar['name'] = 'wangke'
print(foo)
print(bar)
{'age': 18, 'name': 'wangke'}
{'age': 18, 'name': 'wangke'}

引數的預設值僅在函式定義時賦值一次,所以foo

bar 都寫在default字典,表示的是同一個字典。

def decode(data, default=None):
    default = {} if default is None else default
    try:
        return json.loads(data)
    except ValueError:
        return default
{'age': 18}
{'name': 'wangke'}

要點:

① 預設值傳參時,引數的預設值僅在函式定義時賦值一次。對 {}[]等動態值,會產生奇怪的結構。

② 預設值傳參時,實參是可變型別,形參的預設值應寫為 None