python中溢出的int

时间:2014-05-25 18:33:20

标签: c python-3.x porting integer-overflow

我正在将Ian Bell的精英部分从C转换为Python。 C(ab)使用16位整数,溢出。 Python使用神奇的Python整数,但没有。这是一个问题。

我可以定义一个class UInt16:(更新:或者使用内置于UInt16中的ctype),其行为与我想要的一样,但是我必须“强制”整个程序中的每个数字都是UInt16。有什么方法可以告诉我的翻译“嘿,你知道Int吗?好吧,我希望你在每个通常使用其中一个的地方使用这个课程。”

或者,如果失败了,还有另一种简单的方法可以实现整数溢出吗?

2 个答案:

答案 0 :(得分:2)

简答:无法按您的意愿覆盖默认的整数行为。


更长的回答:

首先,我们可以看到Python中存在16位无符号整数的几种实现:

  1. 在内置库ctypes中,16位无符号整数可用作c_uint16
  2. Numpy库还包含unint16
  3. 实现您自己的uint16数据类型(使用运算符重载等)
  4. 我们是否可以使用这些或其他一些数据类型来覆盖Python中的默认整数是一个棘手的问题。

    假设用户使用int方法在程序中创建所有整数。如果是这种情况,那么我们可以包装int方法来创建无符号整数而不是常规整数:

    from ctypes import c_uint16
    _int = int
    
    def int(x):
        return c_uint16(x)
    

    例如,以下代码可以正常工作:

    a = int(1)
    

    我们可以检查:

    >>> type(a)
    <class 'ctypes.c_ushort'>
    

    问题出现了:

    b = 1
    

    在这种情况下,不会调用int方法,而是简单地为b分配值1。我们希望做的是覆盖这种行为,但不幸的是it is not possible

答案 1 :(得分:1)

AFAIR不可能。您想要monkey-patch内置类型,即impossible in python

扩展版

整数文字(1,而不是int(“1”))总是来自builtins / __builtins__模块的int类型(取决于python版本)。你想要做的是基本上将unint16上的所有方法复制到int类(因为方法只是函数类型的属性)。在这种情况下,在您声明的每个地方1,您将获得int类型的对象,其行为与unint16类似。

这在python中是不可能的。我认为由于这个原因,底层实现变得越来越容易,但这背后有更深层次的逻辑。

int是核心类之一,例如liststrobjectsetdicttuple等等。假设有人创建了非常方便的库,几乎每个人都会使用。如果你曾经使用过Java,那么想象一下对Apache Commons或Spring的影响。几乎所有重要的人都会使用它,因为这些东西使开发更快。现在,假设有人创建了fork - 在他的公司内部使用,说他这样做是为了保持代码库稳定 - 这有一小段代码,改变内置object行为,以便它发送一些关键数据给他。他可以用他们的私人数据(地址,然后他将出售,密码,等等)骗取数百万用户。令人毛骨悚然的情景,对吧?

现在,这似乎不太真实,但是如果你让最终用户评估python脚本怎么办?您可能已经看过像gedit这样的文本编辑器或带有内置python shell的音乐播放器(Rhythmbox),为程序内部提供了接口。现在,soemone以某种方式将object行为更改为您的计算机。另一个令人毛骨悚然的情景。

这些是我想到的例子,我真的不记得python的创建者对它的评价 - 这就是为什么我提供了进一步讨论的链接。

有点偏离主题 - 这实际上可能导致一些优秀的库(“这”意味着“允许对内置的猴子修补”)。想象一下猴子修补所有bultins,以便将它们存储在一些多处理管理器中。你几乎可以基于多处理获得java风格的多线程,并且可以以某种方式避免GIL。当然,还有许多其他原因导致这种情况不太好(例如,“多线程的幻觉不是多线程”),但我发现它对简单的日常桌面脚本很有用。