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

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.

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())

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.