OverflowError: Python int太大,不能转换为C长

时间:2022-06-24 18:20:06

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.

它基本上覆盖__add__方法,以便仅在self. sim_observe_window()返回True时添加。

However, if the initial value is too big, I have OverflowError: Python int too large to convert to C long.

但是,如果初始值太大,就会出现OverflowError: Python int太大,无法转换为C long。

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

什么是正确的方法去做我想做的事,同时处理大的数字?

3 个解决方案

#1


7  

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

您使用的是Python 2.6吗?你可以尝试代入long。

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.

但总的来说,我强烈建议不要子类化Python内置类型;CPython保留跳过对此类类型的特殊方法的调用的权利,例如不会调用str子类上的__str__。

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

考虑委托,并委托你想要的操作符。(当然,你也可能希望__________。)

#2


7  

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

我喜欢Eevee关于委派的回答。他没有提供任何代码,所以我在做:

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.

这样,问题就解决了。当我决定对int类型进行子类化时,这是因为我的代码中已经有了一些int变量,并且不想对代码做太多修改。但是,如果我定义__int__和__float__,我只需要向int添加一些强制类型转换,我想如果它能避免奇怪的错误,那就没那么糟糕了。

#3


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:

我解决了一个类似的问题,用int(bigNumber)将它转换为int(int),但在您的例子中,这是微不足道的。你可以试试麻木:

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

致以最亲切的问候

#1


7  

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

您使用的是Python 2.6吗?你可以尝试代入long。

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.

但总的来说,我强烈建议不要子类化Python内置类型;CPython保留跳过对此类类型的特殊方法的调用的权利,例如不会调用str子类上的__str__。

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

考虑委托,并委托你想要的操作符。(当然,你也可能希望__________。)

#2


7  

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

我喜欢Eevee关于委派的回答。他没有提供任何代码,所以我在做:

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.

这样,问题就解决了。当我决定对int类型进行子类化时,这是因为我的代码中已经有了一些int变量,并且不想对代码做太多修改。但是,如果我定义__int__和__float__,我只需要向int添加一些强制类型转换,我想如果它能避免奇怪的错误,那就没那么糟糕了。

#3


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:

我解决了一个类似的问题,用int(bigNumber)将它转换为int(int),但在您的例子中,这是微不足道的。你可以试试麻木:

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

致以最亲切的问候