默认值传参时,实参是可变类型,一定用 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
例如:从 \(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
都写在同一个字典。
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
。