2

Assume I were given the following class:

class foo(object):

    def __init__(self, int):
        self.count = int

    def increment(self, int):
        return foo(int + 1)

    def decrement(self, int):
        return foo(int - 1)

My goal is to chain together function calls to reach the result I want without having to assign each object to a variable. For instance, I know I can do this:

obj = foo(0)
obj = obj.increment(obj.count)
obj = obj.decrement(obj.count)
obj = obj.increment(obj.count)
obj = obj.decrement(obj.count)
print obj.count
0

but I would like to be able to do this:

finalcount = obj(0).increment(?.count).decrement(?.count)

but I don't know if there is something that I can put in place of ? to refer to the object who's method is being called since that object hasn't been assigned a name.

JHixson
  • 1,512
  • 2
  • 14
  • 29
  • Just `return self` at the end of each method. The phrase *"fluent interface"* may help your research. – jonrsharpe Feb 07 '17 at 23:28
  • @jonrsharpe Well, that won't exactly work in the OP's example, where a new instance is created. – wim Feb 07 '17 at 23:31
  • 1
    None of this class's methods actually do anything with its instance variables. Are you sure `increment` and `decrement` are supposed to take an argument for what to increment, rather than incrementing `self.count`? And are you sure they're supposed to be creating a new object instance of modifying (and perhaps returning) `self`? – user2357112 Feb 07 '17 at 23:31
  • @user2357112 if the class design is bad then foret about it. just in general, if the function youa re trying to call does require an argument, and the argument that you want to pass happens to be a member of that class, is it possible? if the answer is no, i'm fine with that. I just wanted to know. – JHixson Feb 07 '17 at 23:39

1 Answers1

1

Your object doesn't really contribute anything in your current code. Note how the methods in your class don't refer to any object state — they never use self. Better would be to omit the int parameter entirely, and use self.count instead:

class foo(object):
    def __init__(self, int):
        self.count = int

    def increment(self):
        return foo(self.count + 1)

    def decrement(self):
        return foo(self.count - 1)

Then, what you wanted to write becomes this:

finalcount = foo(0).increment().decrement()

But, to answer your original question, there is no way to refer to the "current" object in the chain of calls. If you want to refer to an intermediate object, you must assign it to a variable.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • I really just threw together a silly class to ask the real question: is it possible to refer to an object that has been created as part of a chain. I can get into the specific `pandas.dataframe` question that i have in mind, but i was just curious about the ability to do something like this in general where the functions do requre an argument, and the argument that you want to use is a member of the class. – JHixson Feb 07 '17 at 23:36
  • My final paragraph addresses your question, irrespective of the quality of the motivating example. – Rob Kennedy Feb 07 '17 at 23:38
  • Thanks Rob! That really was all I wanted to know. Knowing that, I am able to go and ask a different question about the specific problem that I am running into, It's just that while working on it i got curious about this topic. – JHixson Feb 07 '17 at 23:43