有时候我们想采用一种非静态的类型,来作为关键字参数的默认值。
案例1:打印日志消息的时候,要把相关事件的时间也标注在信息中。
import datetime
from time import sleep
def log(message,when=datetime.datetime.now()):
print("%s:%s"%(when,message))
if __name__=='__main__':
log('hi thers!')
sleep(0.01)
log('Hi again')
输出结果:
2020-02-24 19:43:05.666984:hi thers!
2020-02-24 19:43:05.666984:Hi again
可以看出,两条消息的时间戳是一样的,这是因为datetime.datetime.now()
只执行了一次,也就是默认参数在函数定义的时候执行了一次。
参数的默认值,会在每个模块加载进来的时候求出
,而很多模块都是在程序启动时加载的。包含这段代码的模块一旦加载进来,参数的默认值就固定不变了,程序就不会再次执行datetime.datetime.now()
.
如果想要正确实现动态默认值,可以把默认值设置为None
,并在文档字符串里面把None
对应的实际物理含义给予说明。
def log(message.when=None):
"""Log a message with a timestamp
Args:
message:Message to print
when:datetime of when the message occurred. Defaults to the present time.
"""
when = datetime.datetime.now() if when is None else When
print("%s:%s"%(when,message))
if __name__=='__main__':
log('hi thers!')
sleep(0.01)
log('Hi again')
这是,函数的输出时间戳就不一样了。
2020-02-24 19:52:31.343702:hi thers!
2020-02-24 19:52:31.354693:Hi again