Can a Python Decorator Redirect Flow?

dynamic-python-developer
Python in Plain English
3 min readFeb 3, 2021

--

This is the story of a unique way to handle variable parameters with Python 3.9.1. (See also: this story.)

Photo by Brett Jordan on Unsplash

I ran into an issue while using kwargs with Python 3.9.1 and I resolved this issue with a bit of unique engineering and I am here to take credit for it.

I like to use decorators whenever possible because they tend to make functional programming easier and this is no exception.

import sys
import traceback

class kwargs(object):

def __init__(self, *args, **kwargs):
self.__f__ = args[0]

def __call__(self, f, *args, **kwargs):
try:
def wrapped_f(*args, **kwargs):
get_kwargs = lambda a,k:a[0][-1] if (isinstance(a[0][-1], dict)) else k
return self.__f__(**get_kwargs(args, kwargs))
return wrapped_f
except Exception as ex:
extype, ex, tb = sys.exc_info()
formatted = traceback.format_exception_only(extype, ex)[-1]
print(formatted)

This is the decorator and it does one thing a bit differently than most other decorators. This decorator is more of a placeholder because the parameter for the decorator is a function pointer which means there is no decorated function because the decorated function captures the parameters for another function. And “yes” I know this is non-standard but I can get away with this because I am a non-standard programmer and I am not afraid to say so. I also like to learn things others may tend to call “unnatural”.

Let’s consider how this gets used

plugins_manager = PluginManager(plugins, debug=True)
service_runner = plugins_manager.get_runner()

api = service_runner.exec(twitter_verse, get_api,
**get_kwargs(
consumer_key=consumer_key,
consumer_secret=consumer_secret,
access_token=access_token,
access_token_secret=access_token_secret,
logger=logger))

This is a bit of code that uses a PluginManager to create a service_runner that issues function calls against a module rather than using the typical import mechanism. I wanted to do this to force the modules to be imported at every use rather than being imported once. Importing with every use means the code can change while the mainline code is…

--

--