Как правильно использовать **kwargs
в Python, когда речь идет о значениях по умолчанию?
kwargs
возвращает словарь, но каков наилучший способ установить значения по умолчанию, или он есть? Должен ли я просто получить доступ к нему как словарь? Использовать функцию get?
class ExampleClass:
def __init__(self, **kwargs):
self.val = kwargs['val']
self.val2 = kwargs.get('val2')
Простой вопрос, но на который я не могу найти хорошие ресурсы. Люди делают это по-разному в коде, который я видел, и трудно понять, что использовать.
__init__()
. Может кто-нибудь объяснить, почему это преступление, достойное ворса?self.__dict__update(**kwargs)
может переопределить методы и вызвать другие ошибкиХотя большинство ответов говорят, что, например,
такой же как"
это неправда. В последнем случае
f
может быть вызвано какf(23, 42)
, тогда как в первом случае принимаются только именованные аргументы - никаких позиционных вызовов. Часто вы хотите позволить вызывающей стороне максимальную гибкость, и поэтому вторая форма, как утверждают большинство ответов, предпочтительнее, но это не всегда так. Когда вы принимаете много необязательных параметров, из которых обычно передаются только несколько, может оказаться отличной идеей (избегая аварий и нечитаемого кода на ваших сайтах вызовов!) Принудительно использовать именованные аргументы -threading.Thread
пример. Первая форма - это то, как вы реализуете это в Python 2.Эта идиома настолько важна, что в Python 3 теперь он имеет специальный поддерживающий синтаксис: каждый аргумент после единственного
*
вdef
подписи является ключевым словом, то есть не может быть передан как позиционный аргумент, а только как именованный. Таким образом, в Python 3 вы можете написать код выше:Действительно, в Python 3 вы даже можете иметь аргументы только для ключевых слов, которые не являются необязательными ( аргументы без значения по умолчанию).
Однако в Python 2 впереди долгие годы продуктивной жизни, поэтому лучше не забывать методы и идиомы, которые позволяют реализовывать в Python 2 важные идеи проектирования, которые непосредственно поддерживаются в языке Python 3!
источник
Я предлагаю что-то подобное
А затем используйте значения любым способом
dictionaryA.update(dictionaryB)
добавляет содержимоеdictionaryB
кdictionaryA
перезаписи любых дубликатов ключей.источник
for key in options: self.__setattr__(key, options[key])
и я готов идти. :)Ты бы сделал
или
Если вы используете
pop
, то вы можете проверить, отправлены ли какие-либо ложные значения, и предпринять соответствующие действия (если таковые имеются).источник
.pop
что это поможет вам «проверить, отправлены ли какие-либо ложные значения»?kwargs
по определенной причине.default_value
переданное значение? И удаляет этот ключ потом?Использовать ** kwargs и значения по умолчанию легко. Однако иногда вам не следует использовать ** kwargs.
В этом случае мы не особо используем ** kwargs.
Выше это "зачем?" декларация. Это так же, как
Когда вы используете ** kwargs, вы имеете в виду, что ключевое слово не просто необязательно, а условно. Есть более сложные правила, чем простые значения по умолчанию.
Когда вы используете ** kwargs, вы обычно подразумеваете что-то более похожее на следующее, где простые значения по умолчанию не применяются.
источник
Так
**kwargs
как используется, когда число аргументов неизвестно, почему бы не сделать это?источник
Вот еще один подход:
источник
get_form_kwargs()
). ccbv.co.uk/projects/Django/1.5/django.views.generic.edit/…get_form()
методе показано, как получить аргументы ключевого слова путем переноса на другой метод (get_form_kwargs
как упомянуто выше). Он конкретизирует форму следующим образом :form_class(**self.get_form_kwargs())
.get_form_kwargs()
в представлении подкласса и добавить / удалить kwargs на основе определенной логики. Но это для учебника по Django.Я думаю, что правильный способ использовать
**kwargs
в Python, когда дело доходит до значений по умолчанию, это использовать метод словаряsetdefault
, как указано ниже:Таким образом, если пользователь передает ключевое слово «val» или «val2»
args
, они будут использоваться; в противном случае будут использоваться значения по умолчанию, которые были установлены.источник
Вы могли бы сделать что-то вроде этого
источник
Следуя предложению @srhegde об использовании setattr :
Этот вариант полезен, когда ожидается, что у класса будут все элементы в нашем
acceptable
списке.источник
Если вы хотите объединить это с * args, вы должны оставить * args и ** kwargs в конце определения.
Так:
источник
@AbhinavGupta и @Steef предложили использовать
update()
, что я нашел очень полезным для обработки больших списков аргументов:Что если мы хотим проверить, что пользователь не передал никаких ложных / неподдерживаемых аргументов? @VinaySajip указал, что
pop()
может использоваться для итеративной обработки списка аргументов. Тогда любые оставшиеся аргументы являются ложными. Ницца.Вот еще один возможный способ сделать это, который сохраняет простой синтаксис использования
update()
:unknown_args
являетсяset
содержащими имена аргументов , которые не встречаются в значениях по умолчанию.источник
Другое простое решение для обработки неизвестных или нескольких аргументов может быть:
источник
** kwargs дает свободу добавлять любое количество аргументов ключевого слова. У каждого может быть список ключей, для которых он может устанавливать значения по умолчанию. Но установка значений по умолчанию для неопределенного количества ключей кажется ненужной. Наконец, может быть важно иметь ключи в качестве атрибутов экземпляра. Итак, я бы сделал это следующим образом:
источник