Возможно, вы захотите принять почти произвольные именованные аргументы по ряду причин - и это то, что позволяет вам сделать форма **kw
.
Самая распространенная причина заключается в том, чтобы передать аргументы прямо в какую-то другую функцию, которую вы переносите (декораторы - один из случаев, но FAR - единственный!) - в этом случае **kw
ослабляет связь между оберткой и wrappee, поскольку обертка не должна знать или заботиться обо всех аргументах wrappee. Вот еще одна, совершенно другая причина:
d = dict(a=1, b=2, c=3, d=4)
если все имена должны были быть известны заранее, то очевидно, что такой подход просто не может существовать, верно? И, между прочим, когда это применимо, я очень предпочитаю этот способ сделать диктовку, ключи которой являются буквальными строками:
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
просто потому, что последний довольно пунктуален и, следовательно, менее читабелен.
Если ни одна из веских причин для принятия **kwargs
не применима, не принимайте ее: это так просто. Итак, если нет веской причины разрешать вызывающей стороне передавать дополнительные именованные аргументы с произвольными именами, не допускайте этого - просто избегайте помещать форму **kw
в конце подписи функции в операторе def
.
Что касается , использующего **kw
в вызове, который позволяет вам собрать точный набор именованных аргументов, которые вы должны передать, каждый с соответствующими значениями, в dict, независимо от одной точки вызова , затем используйте этот dict в одной точке вызова. Сравните:
if x: kw['x'] = x
if y: kw['y'] = y
f(**kw)
до:
if x:
if y:
f(x=x, y=y)
else:
f(x=x)
else:
if y:
f(y=y)
else:
f()
Даже с двумя возможностями (и очень простыми!) Отсутствие **kw
позволяет сделать второй вариант абсолютно несостоятельным и невыносимым - просто представьте, как он работает, когда существует полдюжины возможностей, возможно, в немного более насыщенном взаимодействии ... без **kw
жизнь была бы абсолютным адом при таких обстоятельствах!