1

I have a little question about python 3.

I want to create a class, which is using a function from within of that class. Just like:

class Plus:
    def __init__(self, x, y):
        self.x = x
        self.y = y

        self.test()

    def test(self):
        return self.x + self.y

now I am doing something like

a = Plus(5,6)    
print(a)

and python is giving me

<__main__.Plus object at 0x000000000295F748>

and not 11 as I want it. I know that I can get 11 by

a = Plus(5, 6).test()
print(a)

but that's not what I want. I want to call the class and getting the result without adding .test() to it.

Can you help me?

Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116
Steve Iron
  • 241
  • 6
  • 12

4 Answers4

1

I would go for:

class Plus:
    def __init__(self, x, y):
        self.x = x
        self.y = y

        self.test()

    def test(self):
        res = self.x + self.y
        self.__repr__ = lambda:str(res)
        return res

>>> Plus(5,5)
10
>>> a = Plus(5,5)
>>> a
10
>>> a.test()
10

This way you are not recomputing the sum each time you call print, its updated when you call the test method.

Netwave
  • 40,134
  • 6
  • 50
  • 93
  • This won't work as-is; `__repr__` must be callable, which a `str` instance isn't. – Thomas Orozco Nov 19 '15 at 11:19
  • This is an anti-pattern: it will *only* work in Python 2, and then only when `Plus` is an old style class. In new style classes, special methods like `__repr__` are not looked up on the instance, only on the class. A better pattern would be to capture `res` as an attribute and implement an `__repr__` *method* as `return self.res`. – lvc Nov 19 '15 at 13:17
0

You'd need to define a __str__ method for your Plus class:

class Plus:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def test(self):
        return self.x + self.y

    def __str__(self):
        return str(self.test())
Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116
  • @Henrik `__str__` should return a string, though. – Thomas Orozco Nov 19 '15 at 11:18
  • this is exactly my point. if you want `c = a + b`, and `a` is double, `b` is double, you'd expect `c`to be a double .. not a string otherwise what is the result of `Plus(a,b) + Plus(a,b)` ? – Henrik Nov 19 '15 at 11:22
  • @Henrik `__str__` only affects how the object is represented when you call `print(...)` on it (or `str(...)`). It has no bearing whatsoever on the return value of `Plus(a,b) + Plus(a,b)` — that would be controlled by [the `__add__` method](https://docs.python.org/2/reference/datamodel.html#object.__add__). If you don't add an `__add__` method, the above code throws `TypeError:: unsupported operand type(s) for +: 'instance' and 'instance'`. – Thomas Orozco Nov 19 '15 at 11:26
  • @Henrik, you are missunderstanding the problem, Thomas is explaining it properly – Netwave Nov 19 '15 at 11:30
  • 1
    While this is true, you don't see a problem with this design? - if I can use a class just like a function, meaning that if I print it to test the value, and it actually shows a value.. I would expect that actually was function returning a value. Everything else makes it difficult to read the code without inspecting the objects. – Henrik Nov 19 '15 at 11:30
  • @Henrik That depends on how it's used. No, using `__str__` isn't an anti-pattern per-se, but yes, you're right it *can* be mis-used. I don't really think we have enough context here to conclude whether it's being mis-used or not. – Thomas Orozco Nov 19 '15 at 11:32
  • @Thomas Orozco - you are right, edited my answer, and will now shut up ;) – Henrik Nov 19 '15 at 11:33
0

now I am doing something like

a = Plus(5,6)    
print(a)

and python is giving me

<__main__.Plus object at 0x000000000295F748>

and not 11 as I want it. I know that I can get 11 by

a = Plus(5, 6).test()
print(a)

but that's not what I want. I want to call the class and getting the result without adding .test() to it.

I am not sure what do you mean by 'and not 11 as I want it'. If you want Plus(5, 6) to actually return 11 (int instance), you should make Plus a function that returns the sum. Alternatively you can override __new__ method and hook upon object creation -- but this is a bad idea.

What are you trying to achieve?

I doubt, that by 'and not 11 as I want it' you want something special to be printed (formatted, represented). If so, override __str__ or __unicode__ or __repr__ method.

warvariuc
  • 57,116
  • 41
  • 173
  • 227
-1

Edit: ignore this answer, it is a comment on a misinterpretation of the question

This is just wrong. when you instantiate an object, you'd expect to get a reference to that object.

if you just want a global function returning a number, why even bother to make a class with an init?

in python you shouldn't want static class's like in C# for encapsulation. instead name the module something, and use that for encapsulation.

Henrik
  • 2,180
  • 16
  • 29
  • you are getting the reference anyway, its just the representation of the object what he wants to be printed as the number – Netwave Nov 19 '15 at 11:23
  • well that's not my interpretation of that question.. I've now re-read it, and still believes the question concerns getting the number 11 – Henrik Nov 19 '15 at 11:26
  • he want that calling print(a) will return the result of the sum instead of the object memory stuff that python usually prints – Netwave Nov 19 '15 at 11:27
  • If you no longer think your answer is helpful, note that you can delete it rather than editing 'ignore this answer' into it. – lvc Nov 19 '15 at 13:19
  • 1
    @lvc. Thanks, I'll try politely to let you know that I am aware. I was in doubt and decided to re-read http://meta.stackexchange.com/questions/5221/how-does-deleting-work-what-can-cause-a-post-to-be-deleted-and-what-does-that/5222#5222 and decided that while I misunderstood the question, and is a bit embarrassed about it, I still feel the comments to the question only makes sense if the answer remains here and gets downvoted – Henrik Nov 20 '15 at 11:38