捕获溢出错误
Catching OverflowError
在 Python 3 中,我有一个 class 表示值的范围 [x,y] 并计算该范围的长度。
如果长度太大,我不确定如何在 class 本身 中捕获 OverflowError 异常。它仅在使用 class 实例的外部代码中引发...
class ValRange:
val_min = None
val_max = None
range_len = 0
def __init__(self, val_min, val_max):
self.val_min = val_min
self.val_max = val_max
def __len__(self):
if (self.val_min is not None and
self.val_max is not None):
length = 0
try:
length = int(self.val_max) - int(self.val_min) + 1
except OverflowError as e:
# Somehow no exception is caught here...
print('OverflowError...')
length = 10**5 # arbitrarily large number
except Exception as e:
print(e)
if length > 0:
self.range_len = length
return self.range_len
import traceback
import uuid
x = uuid.UUID('00000000-cb9d-4a99-994d-53a499f260b3')
y = uuid.UUID('ea205f99-0564-4aa0-84c3-1b99fcd679fd')
r = ValRange(x, y)
try:
print(len(r))
except:
# The exception is caught in this outer code and not in the class itself. Why?
print(traceback.format_exc())
# The following, which is equivalent to the operations in the
# code above, will work.
a = int(y) - int(x) + 1
print(a)
这是执行时发生的情况:
Traceback (most recent call last):
File "/home/rira/bugs/overflow.py", line 35, in <module>
print(len(r))
OverflowError: cannot fit 'int' into an index-sized integer
311207443402617699746040548788952897867
那是因为 OverflowError
不会出现在你神奇的 __len__()
方法中 - Python 完全有能力处理比它大得多的整数 - 但在 CPython len()
本身实现为 PyObject_Size()
which returns a Py_ssize_t
,仅限于 2^31-1
(32 位)或 2^63-1
(64 位),因此当您的 __len__()
结果是 强制 到它。
您可以在返回结果之前进行预检查,以确保在溢出发生之前捕获它,例如:
def __len__(self):
if (self.val_min is not None and self.val_max is not None):
length = int(self.val_max) - int(self.val_min) + 1
if length > sys.maxsize:
print('OverflowError...')
length = 10**5 # arbitrarily large number
self.range_len = length
return self.range_len
在 Python 3 中,我有一个 class 表示值的范围 [x,y] 并计算该范围的长度。
如果长度太大,我不确定如何在 class 本身 中捕获 OverflowError 异常。它仅在使用 class 实例的外部代码中引发...
class ValRange:
val_min = None
val_max = None
range_len = 0
def __init__(self, val_min, val_max):
self.val_min = val_min
self.val_max = val_max
def __len__(self):
if (self.val_min is not None and
self.val_max is not None):
length = 0
try:
length = int(self.val_max) - int(self.val_min) + 1
except OverflowError as e:
# Somehow no exception is caught here...
print('OverflowError...')
length = 10**5 # arbitrarily large number
except Exception as e:
print(e)
if length > 0:
self.range_len = length
return self.range_len
import traceback
import uuid
x = uuid.UUID('00000000-cb9d-4a99-994d-53a499f260b3')
y = uuid.UUID('ea205f99-0564-4aa0-84c3-1b99fcd679fd')
r = ValRange(x, y)
try:
print(len(r))
except:
# The exception is caught in this outer code and not in the class itself. Why?
print(traceback.format_exc())
# The following, which is equivalent to the operations in the
# code above, will work.
a = int(y) - int(x) + 1
print(a)
这是执行时发生的情况:
Traceback (most recent call last):
File "/home/rira/bugs/overflow.py", line 35, in <module>
print(len(r))
OverflowError: cannot fit 'int' into an index-sized integer
311207443402617699746040548788952897867
那是因为 OverflowError
不会出现在你神奇的 __len__()
方法中 - Python 完全有能力处理比它大得多的整数 - 但在 CPython len()
本身实现为 PyObject_Size()
which returns a Py_ssize_t
,仅限于 2^31-1
(32 位)或 2^63-1
(64 位),因此当您的 __len__()
结果是 强制 到它。
您可以在返回结果之前进行预检查,以确保在溢出发生之前捕获它,例如:
def __len__(self):
if (self.val_min is not None and self.val_max is not None):
length = int(self.val_max) - int(self.val_min) + 1
if length > sys.maxsize:
print('OverflowError...')
length = 10**5 # arbitrarily large number
self.range_len = length
return self.range_len