python 動態預設參數, 執行期
我們在 python 定義一個 function 時,如果想要給定 default argument 可以這樣寫:
def foo(arg=10):
... processing arg ...
但是如果我們今天要使用的預設參數是在動執行期才能夠決定的,而不是靜態時期該怎麼做呢?
例如:我們想要寫一個 log function, 會印出當時訊息的時間, 跟訊息內容def log(msg, when=datetime.now()):
print("{when}: {msg}".format(when, msg))
可是如果我們是用上面的寫法,會發現取到的時間都是一樣的,那是 function 被定義的時間。為了處裡這個問題,我們會先將它設置為 None 再做進一步的處理,然後再利用 docstring 來補充說明 default argument 的用處。def log(msg, when=None):
"""
when 的預設值是 function call 發生的時間,也就是 log message 的時間
"""
when = datetime.now() if when is None else when
... print message ...
因為 default argument 只會被 evaluate 計算一次,所以如果我們使用 [], {} 做為我們的 default argument 有時候會出現不可預期的錯誤。
例如:def to_json(data, default={}):
try:
return json.loads(data)
except ValueError:
return default
json_data1 = to_json('123 321')
json_data1['k1'] = 1
json_data2 = to_json('321 123')
json_data2['k2'] = 2
print(json_data1)
print(json_data2)
上面這段 code 我們預想 json_data1, json_data2 經由觸發 except 所得到的 dict 應該是 {} 且是不同的物件,但是他們卻是相同的!如果你使用 [] 作為 default arguments 也會出現相似的錯誤! 這時候,我們的修正方式也是將他們先設置為 None 在 return 物件
留言
張貼留言