16

文字列を私が書いた拡張するクラスに変換しようとすると、奇妙な動作が見られますint。これが私の問題を示す簡単なプログラムです:

class MyInt(int):
    pass

toInt = '123456789123456789123456789'

print "\nConverting to int..."
print type(int(toInt))

print "\nConverting to MyInt..."
print type(MyInt(toInt))

は空なのでMyInt、とまったく同じように動作することを期待していましたint。代わりに、上記のプログラムから得た出力は次のとおりです。

Converting to int...
<type 'long'>

Converting to MyInt...
Traceback (most recent call last):
  File "int.py", line 9, in <module>
    print type(MyInt(toInt))
OverflowError: long int too large to convert to int

MyInt文字列を!に変換することはできません。私が書いた方法MyIntで、基本クラスとは異なる動作をするのはどうですか?MyIntこの場合、 ;にはある種の最大値があるようです。組み込みクラスがPythonで拡張されたときに、このように暗黙的に課される他のプロパティはありますか?MyIntそして最後に、この最大値をもう持たないように変更する方法はありますか?

4

2 に答える 2

13

秘密はすべて__new__()メソッドにあります:

>>> class MyInt(int): pass
>>> MyInt.__new__ == int.__new__
True
>>> MyInt.__new__(MyInt, '123456789101234567890')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long
>>> MyInt.__new__(int, '123456789101234567890')
123456789101234567890L

__init__(self, *args)基本的に、クラスをインスタンス化するときに(の前に)最初に発生するのは、それ__new__(cls, *args)が呼び出されることです。最初の引数としてクラスオブジェクトが渡されます。(によって継承される)の__new__メソッドは、渡されるクラスがである場合にのみ変換を実行します。に変換すると、追加したすべての特別な機能が削除されるため、これはサブクラスの混乱を避けるためだと思います。intMyIntlongintMyIntlong

long処理できるよりも大きい整数が必要な場合は、基本クラスとして使用する必要がありますint

于 2012-05-24T00:27:06.230 に答える
1

うまくいけば、通訳者とのこのセッションが、何が起こっているかについての洞察を提供するでしょう:

>>> i = 1
>>> print type(i), i
<type 'int'> 1
>>> i = int((i << 31) - 1)
>>> print type(i), i
<type 'int'> 2147483647
>>> i += 1
>>> print type(i), i
<type 'long'> 2147483648
>>> 

intPython はおそらくオブジェクトを特殊なケースとして扱うため、クラスはこの動作を継承していません。

于 2012-05-23T18:46:17.757 に答える