In my package, I have various functions (fun
) that can interact with or modify stuff (for simplicity I use string fragments here), and return it. I now want to create a class that can collect what the functions return (Collector
). I want those functions to become methods of the Collector
class so that they can be called from its namespace - not directly though, but through a subclass which I call run
.
So, when using collector.run.fun()
I would like Collector
to catch the output of fun
so that it is available (in Collector
's namespace) for further processing (e.g. by running more functions).
How do I dynamically add functions to a class and retain what they return in the class?
Here is some code. It's wrong, obviously - setattr
will just attach fun
to Collector.run
...I don't know how to proceed though:
## package structure
## /my_pgk/module.py
## /my_pgk/sub/submodule.py
## many more like this in submodule.py:
def fun(add="default", **kwargs):
if "base" in kwargs:
add = kwargs.get("base") + " " + add
if "more" in kwargs:
add = add + " " + kwargs.get("more")
return add
## in module.py:
from sub import submodule
class Collector(object):
def __init__(self, base, **kwargs):
self.base = base
if "more" in kwargs and not kwargs.get("more") == "":
self.more = kwargs.get("more")
class run(object):
def __init__ (self):
## dyanmically add class methods (this is wrong)
for key, value in submodule.__dict__.items():
if callable(value) and not key.startswith('_'):
setattr(self, key, value)
self.run = run()
## ENTER SOME PYTHON MAGIC HERE THAT ALLOWS ME TO RUN FUNCTIONS AS
## CLASS METHODS AND CATCH THEIR OUTPUT FOR FURTHER PROCESSING:
## self.add = ...SOMEHOW CATCH METHOD OUTPUT...
## self.final = ", and ".join([self.base, self.add, self.more])
def out(self):
print(self.final)
## in practice:
col = Collector(base="(1) this is the start",
more="(3) even more is provided")
col.run.fun("(2) this is what I add")
col.out()
## should give
# (1) this is the start, and (2) this is what I add, and (3) even more is provided