5

我正在浏览six.pydjango utils 中的代码,对于非 Jython 实现,它会尝试找到 int 的 MAXSIZE。现在,这样做的方式很有趣——不是在语句本身上捕获异常,而是将语句包装在__len__自定义类的方法中。这样做的原因可能是什么?

class X(object):
    def __len__(self):
        return 1 << 31
try:
    len(X())
except OverflowError:
    # 32-bit
    MAXSIZE = int((1 << 31) - 1)
else:
    # 64-bit
    MAXSIZE = int((1 << 63) - 1)
del X

如果我没记错的话,同样的也可以缩短到下面,对吧?

try:
    1 << 31
except OverflowError:
    # 32-bit
    MAXSIZE = int((1 << 31) - 1)
else:
    # 64-bit
    MAXSIZE = int((1 << 63) - 1)
4

1 回答 1

4

int在 python3 中是一种多语言类,可以表示机器整数和大整数;int一个取代python2之间和之间区别的功能long。在 python3 上,构造int(1 << n)永远不会引发错误。

所以为了解决这个问题,6 使用了一个巧妙的技巧,迫使python 将一些东西塞进一个机器大小的 int 中。len内置函数总是尝试将返回值转换__len__为机器大小的东西:

>>> class Lengthy(object):
...     def __init__(self, x):
...         self.x = x
...     def __len__(self):
...         return self.x
...     
>>> int(1<<100)
1267650600228229401496703205376L
>>> type(int(1<<100))
<type 'long'>
>>> len(Lengthy(1<<100))
Traceback (most recent call last):
  File "<ipython-input-6-6b1b77348950>", line 1, in <module>
    len(Lengthy(1<<100))
OverflowError: long int too large to convert to int

>>> 

或者,在 Python 3 中,例外情况略有不同:

>>> len(Lengthy(1<<100))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: cannot fit 'int' into an index-sized integer
>>> 
于 2015-05-14T11:46:41.873 回答