4

I would like to change the

float.__str__ 

function of the build in float type (python 2)

I tried to extend this class.

class SuperFloat(float):
    def __str__(self):
        return 'I am' + self.__repr__()

However, when I add it it becomes a normal float

egg = SuperFloat(5)
type(egg+egg)

returns float

My ultimate goal is that also

egg += 5

stays a superfloat

Vasco
  • 1,177
  • 11
  • 28

2 Answers2

6

You will need to override the "magic methods" on your type: __add__, __sub__, etc. See here for a list of these methods. unutbu's answer shows how to do this for __add__ and __radd__, but there are a lot more you will have to override if you want your subclass to be substitutable for the builtin type in any situation. This page has some suggestions on how to make some of that work easier.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • The referenced page is dead. Here is and [archive.org copy](https://web.archive.org/web/20090629065927/http://www.gossamer-threads.com/lists/python/python/739295) or the [official python archive](https://mail.python.org/pipermail/python-list/2009-April/thread.html#683359) – Mohammad Alhashash Jul 13 '22 at 21:45
5
class SuperFloat(float):
    def __str__(self):
        return 'I am ' + self.__repr__()
    def __add__(self, other):
        return SuperFloat(super(SuperFloat, self).__add__(other))
    __radd__ = __add__

In [63]: type(5+egg)
Out[63]: __main__.SuperFloat

In [64]: type(egg+5)
Out[64]: __main__.SuperFloat

In [65]: type(egg+egg)
Out[65]: __main__.SuperFloat

In [67]: egg += 5

In [69]: type(egg)
Out[69]: __main__.SuperFloat
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • What is the difference between `__radd__` and `__add__`? – TheSoundDefense Jul 29 '14 at 18:11
  • 1
    @TheSoundDefense: `5+egg` calls `(5).__add__(egg)` which returns `NotImplemented`. This causes `egg.__radd__(5)` to be called. This gives `egg` a chance to handle the addition. See http://stackoverflow.com/q/1062096/190597. – unutbu Jul 29 '14 at 18:13
  • 1
    This will only fix the problem for `+` specifically, but it seems clear from the question that he wants his subclass to "act like a float" for all operations, which would require overriding many more methods. – BrenBarn Jul 29 '14 at 18:17
  • I think you are reading more into the question than is actually there. The OP says "my ultimate goal is that also `egg += 5` stays a superfloat." – unutbu Jul 29 '14 at 18:26
  • @unutbu: Heh, maybe, but I find it somewhat unlikely that the entire point of the subclass is just to execute that single line of code. He starts off by saying his original goal was to override `float.__str__`, and that override will not take full effect without overriding all the math magic methods. – BrenBarn Jul 29 '14 at 18:29
  • 1
    @BrenBarn Maybe so, but basic code samples can be invaluable when learning how to do that. I especially gave a +1 for the `__radd__ = __add__`, which I would not have thought to do. The answer you gave completely leapfrogs the basics of overriding the magic methods and I feel like that is less helpful than this. – TheSoundDefense Jul 29 '14 at 18:35
  • @BrenBarn: Information on how to more fully subclass `float` is great, but I don't see what I can do about. I could subsume your answer into mine, but I don't think that is polite behavior. – unutbu Jul 29 '14 at 18:41