Reputation: 10043
I've started to build my class
in this fashion (more like a regular function
):
ex 1
class Child(Parent):
def __init__(self,user):
Parent.__init__(self, user)
search = api.search()
filter = api.filter(search)
output = api.output(filter)
return output
this way I could run:
movies = Child('John')
and get my final output.
Then, I broke my global api methods
into instance methods
in order to have more control of data:
ex 2
class Child(Parent):
def __init__(self,user):
Parent.__init__(self, user)
def search_api(self):
search = api.search()
return search
def filter_api(self, search):
filter = api.filter(search)
return filter
def output(self, filter):
output = api.output(filter)
return output
and now I have to break it in different instances, to get the final output:
test = Child('John')
search = test.search_api()
filter = test.filter_api(search)
out = test.output(filter)
print (out)
Is there a decorator
or built-in method
that allows me to chain all instance methods
so that ex2
can be run in one shot (instantiation)?
Upvotes: 0
Views: 323
Reputation: 4461
No need for the magic stuff if you need to make objects behave like function calls you should implement __call__
instead of just packing everything in the constructor.:
class Child(Parent):
def __init__(self,user):
Parent.__init__(self, user)
self.myuser = user
def search_api(self):
search = api.search()
return search
def filter_api(self, search):
filter = api.filter()
return filter
def output(self, filter):
return output
def __call__(self,user):
search = self.search_api()
filter = self.filter_api(search)
return self.output(filter)
And now you can:
a = Child('Joe')
print(a())
Upvotes: 1
Reputation: 7330
I think what you are after is the builder pattern so you could write output = Search().filter().get_output()
or something like that.
For this to work, you need to return the builder object from all the "intermediate" methods:
class Search(object):
def __init__(self, *args, **kwargs):
# apply args, kwargs
def filter(self, *args, **kwargs):
# apply args, kwargs
self.filters.append(...)
return self
def paginate(self, *args, **kwargs):
# apply args, kwargs
self.pagination = ...
return self
def get_output(self, *args, **kwargs):
# apply args, kwargs
# build the search, find output ...
return output
Upvotes: 2
Reputation: 54
You can use __call__()
. I know it's not the same, but perhaps it might be better than your ex2
:
class Child(Parent):
def __init__(self, user):
Parent.__init__(self, user)
def search_api(self):
search = api.search()
return search
def filter_api(self, search):
filter = api.filter(search)
return filter
def output(self, filter):
output = api.output(filter)
return output
def __call__(self):
search = self.search_api()
filter = self.filter_api(search)
return self.output(filter)
Then, you can do:
c = Child("john")
output = c()
Upvotes: 1
Reputation: 85612
Some helpers to make it compile:
class API:
def __getattr__(self, attr):
return API()
def __call__(self, x=1):
return 42
api = API()
class Parent(object):
def __init__(self, user):
self.user = user
Doing all steps in process
method:
class Child(Parent):
def __init__(self, user):
super().__init__(user)
def search_api(self):
search = api.search()
return search
def filter_api(self, search):
filter = api.filter()
return filter
def output(self, filter):
return api.output
def process(self):
res = self.search_api()
res = self.filter_api(res)
return self.output(res)
allows you to do all in one line:
movies = Child('John').process()
Upvotes: 1