扩展int的Python类并不完全像int一样

dsh*_*iro 16 python

在尝试将字符串转换为我编写的扩展类时,我看到了一些奇怪的行为int.这是一个简单的程序,演示了我的问题:

class MyInt(int):
    pass

toInt = '123456789123456789123456789'

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

print "\nConverting to MyInt..."
print type(MyInt(toInt))
Run Code Online (Sandbox Code Playgroud)

既然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
Run Code Online (Sandbox Code Playgroud)

字符串无法转换为MyInt!我写的方式如何MyInt导致它的行为与基类不同?在这种情况下,似乎有某种最大值MyInt; 当在Python中扩展内置类时,还有其他属性会被隐式强加吗?最后,有没有办法改变,MyInt以便它不再具有这个最大值?

Pet*_*ter 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
Run Code Online (Sandbox Code Playgroud)

基本上,当你实例化一个类时,发生(之前__init__(self, *args))的第一件事__new__(cls, *args)就是调用它.它将类对象作为其第一个参数传递.在__new__用于方法int(这是由继承MyInt)仅执行转换到long如果传递的类是int.我假设这是为了避免搞乱子类,因为转换MyIntlong将删除您添加的所有特殊功能.

long如果你想要大于int可以处理的整数,你应该使用你的基类.