dkmatt0
dkmatt0

Reputation: 243

Chaining instance methods in python

I would like create a class in python with method and sub-method.

Example what I want to do :

foo = Foo()
foo.playlist('my playlist').add('i_add_a_track_in_"my playlist".ogg')
foo.playlist('my playlist').delete('i_remove_this_track.ogg')

I have this code for now :

class Foo(object):
    def playlist(self, name):
        pass #my function...
    def add(self, track):
        pass #adding track
    def delete(self, track):
        pass #delete track

Please help me, I don't know how i can do it.

Thank you

Upvotes: 1

Views: 1404

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77942

If I understand correctly, foo.playlist('someplaylist').do_something() should actually be a shortcut for

playlist = foo('someplaylist')
playlist.do_something()

where playlist is NOT a foo object (ie: foo.do_something() is not supposed to make any sense and should just raise an error) but an instance of a distinct class.

If that's indeed the case, you actually want two classes: Foo with method playlist(...) that returns a Playlist object, and Playlist with add() and delete() methods:

class Playlist(object):
    def __init__(self, name):
        self.name = name

    def add(self, what):
        print("adding {} to playlist {}".format(what, self.name))

    def delete(self, what):
        print("deleting {} from playlist {}".format(what, self.name))


class Foo(object):
    def playlist(self, name):
        return Playlist(name)

Upvotes: 1

cs95
cs95

Reputation: 403218

IIUC, you want to chain method calls one after another? All you'd have to do is return self at the end of each function.

class Foo(object):
    ...   
    def playlist(self, name):
        ...
        return self

    ... # and so on

MVCE:

In [229]: class Foo:
     ...:     def __init__(self, data):
     ...:         self.data = data
     ...:
     ...:     def add(self, val):
     ...:         self.data += val
     ...:         return self
     ...:
     ...:     def sub(self, val):
     ...:         self.data -= val
     ...:         return self
     ...:     

In [231]: x = Foo(0)

In [232]: x = x.add(10).sub(5) # or just x.add(10).sub(5)

In [233]: x.data
Out[233]: 5

Upvotes: 3

Related Questions