[英]What is the most Pythonic way to use an empty dictionary as a default argument?
使用x={}
形式的默認參數通常無法在Python中實現預期目的,因為默認參數在定義函數時被綁定,而不是調用。
約定似乎是將可變對象設置為x=None
默認參數,然后在調用函數時檢查x is None
以指定正確的默認值。
因此,如果我想將x
轉換為默認為空的字典,我會使用如下內容:
def f(x=None):
x = dict(x) if x is not None else {}
但是,由於dict
可以采用任何迭代,我也可以寫這個更簡潔的版本:
def f(x=()):
x = dict(x)
以下哪種是“正確的”方法?
慣用的風格是不 dict
; 這樣,有人可以使用任何實現正確映射方法的對象。
所以,最pythonic的方法是使用:
def f(x=None):
if x is None:
x = {}
然后只使用映射方法。
所以,你通常不應該為dict轉換參數。 您聲明您的API 接受映射對象,並期望調用者進行轉換。
接受dict
和iterable的唯一理由是當你想支持允許重復鍵的有序鍵值對時,例如urllib.urlencode
函數 。 在這種情況下, dict
不能保留該信息,並且該方法不會將迭代轉換為dict,而是使用dict作為可迭代。
這里沒有正確或錯誤的答案,但我會說第一個是更慣用的(這不會使第二個錯誤,或壞,或更糟,等等)
需要提到的是,如果函數本身改變了這個dict
,那么空dict
作為參數只是一個問題。 如果只讀取dict
,則不會出現任何問題。
如果有意改變dict
,為什么空dict
作為默認參數有意義呢? 由於呼叫者未提供此信息,因此他們沒有對此進行引用,並且在呼叫之后對dict
所做的更改將丟失。
唯一可能有意義的情況是函數需要做一些需要更改其輸入版本的東西。 在這種情況下,函數應該可以在不直接更改輸入的情況下創建更改的版本,例如:
# bad way:
def f(x={}):
x['newkey'] = 'newvalue'
print(x) # do something with the extended x
# probably better way:
def f(x={}):
new_dict = {}
new_dict.update(x)
new_dict.update({ 'newkey': 'newvalue' })
print(new_dict) # do something with the extended x
以這種方式(后者),原始的x
永遠不會改變,因此不會出現問題。
我知道可變的默認參數問題是眾所周知的,並且被認為是一個問題。 但我也有這種感覺,遇到它只是它出現的代碼結構的一個更深刻的問題的症狀,我想在這篇文章中指出。 或者換句話說:在一個結構合理的代碼片段中,一個可變的默認參數永遠不會導致實際問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.