0

I am trying to make my new code as user friendly as possible and what I would have in mind for the particular problem I am facing atm is this:

Suppose we have

import numpy as np
class TestClass:
 def __init__(self, data):
 self.data = data
 @property
 def method_a(self):
 return np.median(self.data)
 @property
 def method_b(self):
 return np.mean(self.data)
foo = TestClass([1, 2, 5, 7, 12, 6, 3, 37, 16])
print(foo.method_a)
print(foo.method_b)

Everything is fine so far. Method A gives me the median, method B the mean.

During processing I will switch depending on circumstances between both methods. So sometimes I will call method A, sometimes method B. However, what I want is then to continue with a method C, that acts upon the result of either method A or B in such a way

final_result = foo.method_a.method_c

or

final_result = foo.method_b.method_c

I know it is possible to write method C as a function and do it like this:

final_result = method_c(foo.method_a)
final_result = method_c(foo.method_b)

but I think it would make the code easier to read if I could apply method C as stated above.

Is this possible somehow?

thanks

asked Mar 21, 2015 at 14:07
4
  • what do you want to do? if you are trying to process the result of mean and median, why not wrap it first before returning? Commented Mar 21, 2015 at 14:11
  • The mean and median calculations are actually just a placeholder here for much more complicated functions I have implemented myself. Method A does some calculations; method B also, but a little different. The type of the result is always the same. Not sure how wrapping the functions would get me what I want. Can you think of a simple example? Commented Mar 21, 2015 at 14:15
  • Do you ever want to call method_a or method_b without then calling method_c on the result? Commented Mar 21, 2015 at 14:28
  • Consider that right now, method_a and method_b are returning a simple number, and method_c would take that number as a parameter. Your proposed change would mean making a whole new class, or adding state to TestClass, just to enable call-chaining. You would be adding complexity to the implementation of the method, for what's a very debatable increase in readability of the call. Personally, I prefer using parameters and return values over object state whenever appropriate. The rules are a little different at API surfaces, but to make an API friendly you'd ideally only expose one method. Commented Mar 21, 2015 at 16:47

3 Answers 3

2

your statement is not quite clear, let's assume you want to add method C to the class. you can wrap your return value inside of the class again to achieve what you want:

import numpy as np
class TestClass:
 def __init__(self, _data):
 self._data = data
 @property
 def data(self): return self._data
 @property
 def method_a(self):
 return TestClass(np.median(self.data))
 @property
 def method_b(self):
 return TestClass(np.mean(self.data))
 @property
 def method_c(self):
 return TestClass(np.whatever(self.data))

then you can chain however long you want:

final_result = foo.method_a.method_b.method_c.method_c.data

if the class is not what you plan to place, you put different one.

answered Mar 21, 2015 at 14:26
Sign up to request clarification or add additional context in comments.

1 Comment

Humm. I did not manage to implement your ideas directly in my code, however, I dd not know that one can wrap a return value inside another class. 😊 With this I simply moved my Methods A and B to the parenting class and returned a new class for which then method C can be applied in the way I want. Hard to describe what I did, but your comment helped 😊
0

Following HuStmpHrrr's comment I changed my code like this (Here I just assume that method C simply adds 1 to the results):

import numpy as np
class NewClass:
 def __init__(self, data):
 self.data = data
 def method_c(self):
 return self.data + 1
class TestClass:
 def __init__(self, data):
 self.data = data
 @property
 def method_a(self):
 return NewClass(np.median(self.data))
 @property
 def method_b(self):
 return NewClass(np.mean(self.data))
foo = TestClass([1, 2, 5, 7, 12, 6, 3, 37, 16])
result1 = foo.method_a
result2 = foo.method_b
print(result1.method_c())
print(result2.method_c())
answered Mar 21, 2015 at 15:26

Comments

0

I'm not sure why you want a property. Your code seems like it really just needs a simple method. Properties are for data that you would get and set that you want to manage.

class Test(Object):
 def __init__(self, data):
 super().__init__()
 self.data = data
 self.value = 0
 # end Constructor
 def method_a(self):
 return np.median(self.data)
 # end method_a
 @property
 def method_c(self):
 return self.value
 @method_c.setter
 def method_c(self, value):
 self.value = value
 # self.method_a(value)
 # end method_c
# end class Test
t = Test([1,2,3,4])
print(t.method_a())
t.method_c = 5 # This calls the method_c.setter and will make t.value = 5
print(t.method_c)

The property is typically used as a wrapper method to control the data.

answered Mar 21, 2015 at 16:39

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.