Skip to content

Instantly share code, notes, and snippets.

@StiiCeva
Created February 26, 2020 21:48
Show Gist options
  • Save StiiCeva/0f62f0cb7ae822514b25a9dedcbcb3aa to your computer and use it in GitHub Desktop.
Save StiiCeva/0f62f0cb7ae822514b25a9dedcbcb3aa to your computer and use it in GitHub Desktop.
Use a function call at a later time and use the result at a later time
class ActionBase:
"""
class ActionBase : fn is mandatory and should be a callable.
You can pass arguments and keyword arguments at instantiation, but you can also pass "named parameters" ( with
'set_params_at_runtime' method) at runtime from an object ( from example a.c will return 2 at the moment of
execution, but at instance creation is None ).
By default the object will store the returned value of the executed function in self.result, but you can also
store data in another object by using 'set_store_result_in' method (example a.set_store_result_in(b,"some_attr")
after a() will save data in b.some_attr)
.
"""
def __init__(self, fn, *args, **kwargs):
if hasattr(fn, '__call__') is False:
raise TypeError("Pass a callable object")
self.fn = fn
self.args = args
self.kwargs = kwargs
self.params_from_class = list()
self.store_in_class = list()
self.result = None
self._debug = False
self._no_initial_params = True
if args == () and kwargs == {}:
self._no_initial_params = False
def set_params_at_runtime(self, cls, attr, named=None):
"""
Method - Configures a named parameter that will be passed the value of getattr(cls, attr) at runtime
:param cls: object
:param attr: string - attribute name
:param named: string - kwargs expected name
:return: None
"""
if self._debug:
logging.warning(">>> set_params_at_runtime : class {}, attr {}, named {} ".format(cls, attr, named))
print(" ", dir(cls.aaa))
if named is None:
raise ValueError("No 'named' parameter was passed")
self._no_initial_params = True
self.params_from_class.append((cls, attr, named))
def set_store_result_in(self, cls, attr):
"""
Method - Configures an external object's attribute in which it will store the result of 'self.execute'
:param cls: object
:param attr: string - attribute name
:return: None
"""
if self._debug:
logging.warning(">>> set_store_result_in : class {}, attr {} ".format(cls, attr))
self.store_in_class.append((cls, attr))
def execute(self):
"""
Method execute populates kwargs with the parameters configured with 'set_params_at_runtime' method
:return: None
"""
args = self.args
kwargs = self.kwargs
for cls, attr, named in self.params_from_class:
kwargs[named] = getattr(cls, attr)
self.result = self.fn(*args, **kwargs)
if len(self.store_in_class) > 0:
for cls_store, attr_store in self.store_in_class:
setattr(cls_store, attr_store, self.result)
return self.result
def __call__(self, *args, **kwargs):
"""
Shadow of self.execute()
If you haven't passed any arguments at initialization, the instance can be called like a function with \
parameters args and kwargs, otherwise it ignores the passed parameters and uses self.execute() with the
settings from __init__.
"""
if self._no_initial_params:
return self.execute()
else:
self.result = self.fn(*args, **kwargs)
return self.result
def __str__(self):
return "{} - args {} , kwargs {} , STORE {}, EXTRA P {}".format(self.__class__.__name__, self.args, self.kwargs,
self.store_in_class, self.params_from_class)
def __unicode__(self):
return "{} - args {} , kwargs {} , STORE {}, EXTRA P {}".format(self.__class__.__name__, self.args, self.kwargs,
self.store_in_class, self.params_from_class)
def __repr__(self):
return "{} - args {} , kwargs {} , STORE {}, EXTRA P {}".format(self.__class__.__name__, self.args, self.kwargs,
self.store_in_class, self.params_from_class)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment