首先與您當前的解決方案來解決這些問題:
def f(**kwargs):
ps = {'c': 2}
ps.update(kwargs)
print(str(ps))
這將創建一個新的字典,然後必須花時間與kwargs所有的值更新它。如果kwargs很大,可能相當低效,正如你指出的那樣有點醜陋。
顯然你的第二個是無效的。
至於第三個選項中,一個實現已經由Austin Hastings
如果您正在使用默認值kwargs而不是關鍵字參數給出有可能是一個原因(或者至少應該有;例如一界面,其定義了c
而沒有明確要求a
和b
可能不被期望,即使該實現可能需要值爲c
)。
簡單的執行採取的dict.setdefault
優勢,以更新kwargs的值當且僅當關鍵是不存在:
def f(**kwargs):
kwargs.setdefault('c', 2)
print(str(kwargs))
現在,作爲在之前的評論中提及了由OP,名單默認值可能是相當長的,在這種情況下,你可以有一個循環設置默認值:
def f(**kwargs):
defaults = {
'c': 2,
...
}
for k, v in defaults.items():
kwargs.setdefault(k, v)
print(str(kwargs))
一對夫婦的性能問題在這裏。首先defaults
字典在函數的每次調用時都會被創建。這可由該函數的外部移動的默認值等從而加以改進:
DEFAULTS = {
'c': 2,
...
}
def f(**kwargs):
for k, v in DEFAULTS.items():
kwargs.setdefault(k, v)
print(str(kwargs))
其次在Python 2,dict.items
返回(鍵,值)的副本對這樣反而dict.iteritems
或dict.viewitems
允許你迭代內容並因此更高效。在Python 3中,'dict.items`是一個視圖,所以這裏沒有問題。
DEFAULTS = {
'c': 2,
...
}
def f(**kwargs):
for k, v in DEFAULTS.iteritems(): # Python 2 optimization
kwargs.setdefault(k, v)
print(str(kwargs))
如果效率和兼容性都擔心,你可以使用six
庫的兼容性如下:
from six import iteritems
DEFAULTS = {
'c': 2,
...
}
def f(**kwargs):
for k, v in iteritems(DEFAULTS):
kwargs.setdefault(k, v)
print(str(kwargs))
此外,在for
循環的每次迭代中,的setdefault
方法的查找需要執行kwargs
。如果你真的有一個非常大的數量的默認值的微優化的方法分配給一個變量,以避免重複查找:
from six import iteritems
DEFAULTS = {
'c': 2,
...
}
def f(**kwargs):
setdefault = kwargs.setdefault
for k, v in iteritems(DEFAULTS):
setdefault(k, v)
print(str(kwargs))
最後,如果默認值的數量,而不是預計會比大kwargs的數量,用kwargs更新默認值可能會更高效。爲此,您不能使用全局默認值,或者每次運行該函數時都會更新默認值,因此需要將默認值移回到函數中。這將使我們有以下幾點:
def f(**kwargs):
defaults = {
'c': 2,
...
}
defaults.update(kwargs)
print(str(defaults))
享受:d
你的第一種方法是不夠好。 – hallazzang
檢查[請求庫](https://git.io/vSRf8),它使用相同的方法。 – hallazzang