有時候我們想採用一種非靜態的類型,來作爲關鍵字參數的默認值。
案例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