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
致以最亲切的问候