在尝试将字符串转换为我编写的扩展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
,让它不再有这个最大值?
发布于 2012-05-24 08:27:06
秘诀在于__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)
。将类对象作为其第一个参数传递给它。int
的__new__
方法(由MyInt
继承)仅在传递的类为int
时才执行到long
的转换。我假设这是为了避免打乱子类,因为将MyInt
转换为long
会删除您添加的所有特殊功能。
如果你想要大于int
处理能力的整数,你应该使用long
作为你的基类。
发布于 2012-05-24 02:46:18
希望这次与解释器的会议将提供一些关于正在发生的事情的洞察:
>>> 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
>>>
您的类不会继承此行为,因为Python可能会将int
对象视为特例。
https://stackoverflow.com/questions/10725057
复制相似问题