kwargs parsing best practice

Question:

Is there a more compact/efficient way of doing this?

    for key in kwargs:
        if key == 'log':
            self.log = kwargs[key]
        elif key == 'bin':
            self.bin = kwargs[key]
        elif key == 'pid':
            self.pid = kwargs[key]
        elif key == 'conf':
            self.conf = kwargs[key]
Asked By: nnachefski

||

Answers:

for k,v in kw.items():
   setattr(self, k, v)
Answered By: Andreas Jung

To achieve exactly what you asked for, you could use

for key in ('log', 'bin', 'pid', 'conf'):
    if key in kwargs:
        setattr(self, key, kwargs[key])

or

self.__dict__.update((key, kwargs[key])
                     for key in ('log', 'bin', 'pid', 'conf')
                     if key in kwargs)

However, I would generally prefer something like this:

def f(log=None, bin=None, pid=None, conf=None):
    self.log = log
    self.bin = bin
    self.pid = pid
    self.conf = conf

While this is still somewhat repetitive, the code is really easy to read. All attributes are intialized regardles of whether the corresponding keyword argument is passed in, and the signature of the function clearly documents the arguments and there defaults.

Answered By: Sven Marnach

If the key provided in get() is not in the dictionary the result is None.

self.log = kwargs.get('log')
self.bin = kwargs.get('bin')
self.pid = kwargs.get('pid')
self.conf = kwargs.get('conf')
Answered By: Andrew Clark

self.__dict__.update(kwargs)

Answered By: lazy1
self.log = kwargs.get('log', default_log)
self.bin = kwargs.get('bin', default_bin)
self.pid = kwargs.get('pid', default_pid)
self.conf = kwargs.get('conf', default_conf)

This has the additional advantage that self.log is assigned in any case (AttributeError means your code is broken as hell, nothing more. Always make sure everything is always assigned.). Without extra self.log = default_log lines. You can omit the default to get None.

Answered By: user395760
for k,v in kwarg.iteritems():
   setattr(self, k, v)

In which setattr(self, "bin", "val") is like calling self.bin = "val"

However it is more desirable to have a whitelist like @Sven Marnach has.

Answered By: Mike Lewis

My solution for this is:

for key in ('log', 'bin', 'pid', 'conf'):
    setattr(self, key, kwargs.get(key, None))

In this mode, all attributes are initialized.

When I have a large number of attributes, I prefer to create a list to be easier to read like this:

kwargs_list = [
    "log",
    "bin",
    "pin",
    "conf"
]

for key in kwargs_list:
    setattr(self, key, kwargs.get(key, None))
Answered By: Luciano Marqueto
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.