第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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章