第20条 用None和文档字符串来描述具有动态默认值的参数

有时候我们想采用一种非静态的类型,来作为关键字参数的默认值。
案例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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章