Taking advantage of *args and **kwargs

Posted by wocos on Thursday, March 9, 2023

Taking Advantage of *args and **kwargs

I consistently forget the option word I have included in a function and so I had to design a way to accept different keywords (option) names to trigger features with in a function.

As an example, assigning a color to a box border is very easy by just adding something like this to a function’s arguments:

’’' def buildabox(msg, border_color=“red”): """ docs go here to put a box around msg """ … ’''

But, if you accidenally call the function like this, it will fail. my_box = buildabox(“my message”, box_color=“white on back”): …

Or maybe you used this and it will fail again.. my_box = buildabox(“my message”, box_clr=“white on back”): …

So there is a way to deal with all of those possibilities using **kwargs and using the function kvarg_val() listed here below.

So instead of declaring each key-value pair we can do this:

’’' def buildabox(msg, **kwargs): """ docs go here to put a box around msg """ box_clr = kvarg_val([“border_color”, “border_clr”, ‘box_color’, “box_clr”], kwargs, dflt=“red”)

now, if any key is used that is in that list box_clr reflect the value provided

and if none is provided then the default assignment of “red”

… ’’'

Now, what about a boolean value where you use a similar key word but not the stipulated var name. For example:

’’' def buildabox(msg, display=False, **kwargs): """ docs go here to put a box around msg options: - display: bool returns lines suitable for printing the returned box """ box_clr = kvarg_val([“border_color”, “border_clr”, ‘box_color’, “box_clr”], kwargs, dflt=“red”) … returns lines ’’'

If I call this function like this it will fail:

’’' lines = buildabox(“my message”, ‘print’, box_clr=“white”): ’’'

Unless I take advantage of *args and use the bool_val function below… like this

’’' def buildabox(msg, *args, **kwargs): """ docs go here to put a box around msg options: - display: bool returns lines suitable for printing the returned box """ box_clr = kvarg_val([“border_color”, “border_clr”, ‘box_color’, “box_clr”], kwargs, dflt=“red”) display = bool_val([“display”, “print”, “prnt”, “show”], args, kwargs, dflt=False)

Now this call will work:

buildabox(msg, ‘show’, box_color=“yellow! on black”) # or any key-name listed

… returns lines ’’’

There are probably better ways to do this but this works for me.

’''

def kvarg_val(key, kwargs_d={}, *args, **kwargs): # ################################### """ purpose: returns a value when the key in a key=value pair matches any key given NOTE: key can be a string or a list of strings option: dflt=“Whatever default value you want” use: used in function to get a value from a kwargs ky=value pair - eg: def my_function(*args, **kwargs): txt_center = kvarg_val([“text_center”, “txt_cntr”, “txtcntr”], kwargs, dflt=1) - so if you call my_function(txt_center=99) then txt_center will be set to 99 — If any key in the list is set = to a value, that value is returned see: bool_val which process both args and kvargs and returns bool_val input key(string), kvargs_d(dictionary of key,vals), default(string; optional) purpose: return a value given by a key=value pair using a matching key (in key list if desired) options: - key provided can be a string or a list of strings - dflt=“Whatever default value you want - can be a string, list, int, float… whatever” <– this is optional, if not declared "" is returned if key in kvargs: return val else: return default returns str(key_val) or default_val(which is "" if none is provided) """ “”"–== Init ==–""" required = False if “required” in args: required = True if ‘required’ in list(kwargs.keys()): required = True mydflt = "" if ‘dflt’ in kwargs: mydflt = kwargs[‘dflt’] “”"–== Validate ==–""" if required: found_flag = False for my_k in kwargs_d.keys(): if my_k in key: found_flag = True if not found_flag: dbug(f"A value for a key: {key} is required for this operation.", ‘ask’, ‘boxed’) “”"–== Init ==–""" my_val = mydflt if not isinstance(kwargs_d, dict): dbug(f"Supplied kwargs_d: {kwargs_d} MUST be a dictionary! Returning…") return “”"–== Convert ==–""" if isinstance(key, list): keys = key else: keys = [key] “”"–== Process ==–""" for k in keys: if k in kwargs_d: my_val = kwargs_d[k] if my_val == “False”: my_val = False if my_val == “True”: my_val = True return my_val # ### EOB def kvarg_val(key, kwargs_d={}): ### # ’’’

’’’

def bool_val(key_l, args_l, kvargs={}, **kwargs): # ####################################### """ purpose: look at args and kwargs with a list of possible option strings and return the default True or False requires: - key_l: str | list # this is the string or list of strings to check args and kwargs against options: - default | dflt: bool # the default value to return - opposite | opposites: str | list # a list of opposites eg: prnt = bool_val([“print”, “prnt”], args, kwargs, dflt=True, opposites=[’noprnt’, ’no_prnt’, ’no_print’]) return True or False Notes: key_l can be a str or list args_l must be provided kvargs is optional used to see if a string or a list of stings might be declared true by being in args or seeing it has a bool value set in kvargs use: DBUG = bool_val(‘dbug’, args, kvargs) or DBUG = bool_val([‘dbug’, ‘DBUG’], args, kvargs) """ “”"–== Config ==–""" bool_v = kvarg_val([“default”, “dflt”], kwargs, dflt=False) opposite_words = kvarg_val([‘opposite’, ‘opposites’], kwargs, dflt=[]) “”"–== Validate ==–""" if not isinstance(opposite_words, list) and opposite_words != []: opposite_words = [opposite_words] “”"–== Convert ==–""" if isinstance(key_l, str): key_l = [key_l] # make it a list for k, val in kvargs.items(): if kvargs[k] == “False”: kvargs[k] = False if kvargs[k] == “True”: kvargs[k] = True “”"–== Init ==–""" opposite_b = False “”"–== Process ==–""" for key in key_l: if key in args_l: bool_v = True if key in kvargs: bool_v = kvargs[key] for word in opposite_words: if word in args_l: opposite_b = True if word in kvargs: # convert strings to boolean when needed if kvargs[word] == “False”: kvargs[word] = False if kvargs[word] == “True”: kvargs[word] = True if isinstance(kvargs[word], bool): opposite_b = kvargs[word] if opposite_b: bool_v = False return bool_v ’’’

Enjoy!


comments powered by Disqus