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

intin python3 は、マシンの int と big-int を表すことができる poly-glot の種類のクラスです。intpython2 のとの区別に取って代わる機能ですlong。Python3 では、構築int(1 << n)でエラーがスローされることはありません。

それを解決するために、six は巧妙なトリックを使用して、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 に答える