I build cloud-based systems for startups and enterprises. My background in operations gives me a unique focus on writing observable, reliable software and automating maintenance work.
I love learning and teaching about Amazon Web Services, automation tools such as Ansible, and the serverless ecosystem. I most often write code in Python, TypeScript, and Rust.
B.S. Applied Networking and Systems Administration, minor in Software Engineering from Rochester Institute of Technology.
Ever want to write functions that flexibly receive arguments? What about getting defaults from a configuration on the module level, then have those defaults automatically used by functions in your module?
Well kwargs might be just what you need. “kwarg” is a nickname for “keyword arguments”, which you’re likely already familiar with in a format like this:
def func(first='ask questions', second='shoot'):
print '{0} first'.format(first)
print '{0} second'.format(second)
if __name__ == '__main__':
func()
Let’s try it out!
$ python test.py
ask questions first
shoot second
Now that’s all well and good, of course, but what if you you need to set those defaults on the fly, say, from a config file that your program reads on startup. Let’s say your config file looks like this.
[Defaults]
first = shoot
second = ask_questions
And this is the code that will read the config.
from ConfigParser import ConfigParser
conf = ConfigParser()
conf.read('test.cfg')
conf_dict = dict(conf.items('Defaults'))
def func(**kwargs):
# the name selected for kwargs is not important, what's special is the **
# any arguments we need that weren't in kwargs, get them from conf_dict
kwargs.update(conf_dict)
print '{0} first'.format(kwargs['first'])
print '{0} second'.format(kwargs['second'])
if __name__ == '__main__':
func()
print 'maybe something more conservative...'
func(second='more questions', first='ask questions')
The program now gives different output.
$ python with_kwargs.py
shoot first
ask questions second
maybe something more conservative...
ask questions first
more questions second
An alternative to having default arguments from a config file would be something like this. The values remain hardcoded, unfortunately, but it allows you to have defaults for kwargs.
def func(**kwargs):
# the .get() function takes a second argument, which is returned by default
# if there is no value for that key
print '{0} first'.format(kwargs.get('first', 'shoot'))
print '{0} second'.format(kwargs.get('second', 'ask questions'))
So now we have a program that does a similar thing to our original, but none of the defaults are hardcoded (except the config file, but let’s ignore that).
The uses of **kwargs go beyond this, of course, they’re great for making extremely flexible functions that are tolerant to non-consistent use.