I wish to have an interactive shell that allows me to perform data manipulation using a series of modules defined in my package. For example, I want to be able to type:
$ Input('data.csv')
$ GroupBy('key')
$ Output('data.csv')
Where Input
, GroupBy
and Output
are all modules/classes of my package that implicitly operate on some 'global' data
iterator. The easy way to do this would be to explicitly pass data
as an argument, but I want the control over what happens to data
to be in the background (maybe I'm distributing it across compute cores and map-reducing, without the user knowing).
This is the closest I've got so far:
class env(object):
def __init__(self):
self.data = []
code.interact(local=locals())
def __iter__(self):
return self.data
def run(self, className, *args, **kwargs):
c = globals()[className](*args, **kwargs)
self.data = chain(self.data, c)
def __getattr__(self, attrName, *args, **kwargs):
return partial(self.run, attrName)
Then within my package __init__.py
I instigate env
. My env.py
will then import the rest of the package modules into it's own namespace (for example Input
, GroupBy
and Output
), which let's me do:
$ self.Input('data.csv')
$ self.GroupBy('key')
$ self.Output('data.csv')
So close, but I want to get rid of the self
!
I thought what I could do was make my env
class inherit from dict
, and then do code.interact(local=self)
, but sadly this does not seem to work?
Please tell me how to achieve this in a Pythonic way (or explain why what I'm trying to do is not Pythonic and offer an alternative), otherwise I'm going to be very naughty and add data
to builtins
so I can access it globally across modules...
tl,dr; How do I wrap all of my package's modules within a class that controls access to global data?