9

I have this class:

class MetricInt(int):
    """Int wrapper that adds only during the observation window."""
    def __new__(cls, _, initial):
        return int.__new__(cls, initial)

    def __init__(self, sim, initial):
        int.__init__(initial)
        self.sim = sim

    def __add__(self, val):
        if self.sim.in_observe_window():
            self = MetricInt(self.sim, super(MetricInt, self).__add__(int(val)))
        return self

Which basically overwrite the __add__ method in order to only to the addition if self.sim.in_observe_window() returns True.

However, if the initial value is too big, I have :

OverflowError: Python int too large to convert to C long.

What is the correct way to do what I'm trying to do and also handle big numbers?

realr
  • 3,652
  • 6
  • 23
  • 34
Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75

3 Answers3

7

Are you on Python 2.6? You could try subclassing long instead.

But in general I strongly suggest not subclassing Python built-in types; CPython reserves the right to skip calls to special methods on such types, and for example will not call __str__ on a subclass of str. Your example here works, but you might be asking for bugs.

Consider delegating instead, and delegating the operators you want. (You may also want __int__, of course.)

Eevee
  • 47,412
  • 11
  • 95
  • 127
7

I like Eevee's answer about delegating instead. He has not provided any code so I'm doing it:

class MetricInt(object):
    """Int wrapper that adds only during the observation window."""
    def __init__(self, sim, initial):
        self.sim = sim
        self.val = int(initial)

    def __add__(self, val):
        if self.sim.in_observe_window():
            self.val += int(val)
        return self

    def __int__(self):
        return self.val

    def __float__(self):
        return float(self.val)

This way, the problem is solved. When I decided to subclass the int type, it was because I already had a few int variables in my code and did not wanted to change my code too much. However, if I define __int__ and __float__, I only need to add some casts to int. It's not that bad I guess if it avoids weird bugs.

Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75
2

I solved a similar problem casting it to int with int(bigNumber) but in think that is trivial in your case. You can try with the numpy:

numpy.int32(Your big number)

And these that I found somewhere that now I can't remember:

def int_overflow(val):
  if not -sys.maxint-1 <= val <= sys.maxint:
    val = (val + (sys.maxint + 1)) % (2 * (sys.maxint + 1)) - sys.maxint - 1
  return val

Credits to the author.

You can pass the overflowed value throught this function and get it normalized.

Best regards

Andoni Diaz
  • 55
  • 1
  • 6