为什么 six.py 使用自定义 class 来查找 MAXSIZE?
Why does six.py use custom class for finding MAXSIZE?
我正在查看 six.py
in the django utils 的代码,对于非 Jython 实现,它试图找到 int 的 MAXSIZE。现在,这样做的方式很有趣——不是在语句本身捕获异常,而是将语句包装在自定义 class 中的 __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)
python3 中的 int
是 class 的多语言类型,可以表示机器整数和大整数;取代 python2 中 int
和 long
之间区别的功能。在 python3 上,构造 int(1 << n)
永远不会引发错误。
因此,为了解决这个问题,六使用了一个巧妙的技巧,即 强制 python 将某些内容塞入机器大小的 int 中。 len
内置函数总是尝试将 __len__
的 return 值转换为机器大小的东西:
>>> 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
>>>
或者,在Python3中,异常略有不同:
>>> len(Lengthy(1<<100))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: cannot fit 'int' into an index-sized integer
>>>
我正在查看 six.py
in the django utils 的代码,对于非 Jython 实现,它试图找到 int 的 MAXSIZE。现在,这样做的方式很有趣——不是在语句本身捕获异常,而是将语句包装在自定义 class 中的 __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)
int
是 class 的多语言类型,可以表示机器整数和大整数;取代 python2 中 int
和 long
之间区别的功能。在 python3 上,构造 int(1 << n)
永远不会引发错误。
因此,为了解决这个问题,六使用了一个巧妙的技巧,即 强制 python 将某些内容塞入机器大小的 int 中。 len
内置函数总是尝试将 __len__
的 return 值转换为机器大小的东西:
>>> 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
>>>
或者,在Python3中,异常略有不同:
>>> len(Lengthy(1<<100))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: cannot fit 'int' into an index-sized integer
>>>