14

I have a class and some methods of it. Could I keep a result of the methods between calling.

Example calling:

result = my_obj.method_1(...).method_2(...).method_3(...)

when method_v3(...) received a result from the method_2(..) who received a result from the method 1(..)

Please tell me, are there patterns or anything to decide above example?

Abbasov Alexander
  • 1,848
  • 1
  • 18
  • 27
  • See also: [Python: jQuery-like function chaining?](http://stackoverflow.com/q/4342977/188535) – detly Jun 26 '13 at 13:31

2 Answers2

18

There is a pretty straightforward pattern called the Builder Pattern where methods basically return a reference to the current object, so that instead of chaining method calls on one another they are chained on the object reference.

The actual Builder pattern described in the Gang of Four book is a little verbose (why create a builder object) instead just return a reference to self from each setXXX() for clean method chaining.

That could look something like this in Python:

class Person: 
   def setName(self, name):
      self.name = name
      return self   ## this is what makes this work

   def setAge(self, age):
      self.age = age;
      return self;

   def setSSN(self, ssn):
      self.ssn = ssn
      return self

And you could create a person like so:

p = Person()
p.setName("Hunter")
 .setAge(24)
 .setSSN("111-22-3333")

Keep in mind that you will actually have to chain the methods with them touching p.a().b().c() because Python doesn't ignore whitespace.

As @MaciejGol notes in the comments you can assign to p like this to chain with whitespace:

p = (
   Person().setName('Hunter')
           .setAge(24)
           .setSSN('111-22-3333')
)

Whether or not this is the best style/idea for Python I can't say, but this is sort of how it would look in Java.

Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170
  • Thanks. I do clarify question I need to filter of data without modify original instance. – Abbasov Alexander Jun 26 '13 at 13:57
  • You can actually indent the calls like in your snippet by wrapping the whole thing in parens, like so http://pastebin.com/SJXfYdxv – Maciej Gol Apr 01 '15 at 08:39
  • @MaciejGol Neat. Does that create a 1-tuple, then assign it out to `p`? – Hunter McMillen Apr 01 '15 at 12:33
  • 3
    No, a 1-element tuple would be created if there was a comma at the end. All it does is it hints the interpreter that the expression will span multiple lines - same goes for multiline strings concatenation, multiple imports etc. It saves you from escaping the newline feed with ```\``` at the end of each line, which in my opinion causes eyes to bleed. – Maciej Gol Apr 01 '15 at 13:06
0

There are multiple choices which would entirely depend on your complete scenario -

  1. Chain of Responsibility - If your different classes needs to follow a chain of operations.
  2. Decorator - When you dont know which sequence you need to top up your class object with additional features
  3. Builder - which would help you to assign parameter values to your class.
JustCode
  • 312
  • 1
  • 3
  • I use Django. My instance has data from the mongodb. I want filter it by methods without modifing original instance. Maybe you know What is kind the best? – Abbasov Alexander Jun 26 '13 at 13:54
  • My suggestion would be if you want only a series of filtering then go for chain of responsibility. I am assuming here that your sequence of filter operation does not change. – JustCode Jun 26 '13 at 13:56