我正在将Ian Bell的精英部分从C转换为Python。 C(ab)使用16位整数,溢出。 Python使用神奇的Python整数,但没有。这是一个问题。
我可以定义一个class UInt16:
(更新:或者使用内置于UInt16中的ctype),其行为与我想要的一样,但是我必须“强制”整个程序中的每个数字都是UInt16
。有什么方法可以告诉我的翻译“嘿,你知道Int
吗?好吧,我希望你在每个通常使用其中一个的地方使用这个课程。”
或者,如果失败了,还有另一种简单的方法可以实现整数溢出吗?
答案 0 :(得分:2)
简答:无法按您的意愿覆盖默认的整数行为。
更长的回答:
首先,我们可以看到Python中存在16位无符号整数的几种实现:
ctypes
中,16位无符号整数可用作c_uint16
unint16
我们是否可以使用这些或其他一些数据类型来覆盖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
是核心类之一,例如list
,str
,object
,set
,dict
,tuple
等等。假设有人创建了非常方便的库,几乎每个人都会使用。如果你曾经使用过Java,那么想象一下对Apache Commons或Spring的影响。几乎所有重要的人都会使用它,因为这些东西使开发更快。现在,假设有人创建了fork - 在他的公司内部使用,说他这样做是为了保持代码库稳定 - 这有一小段代码,改变内置object
行为,以便它发送一些关键数据给他。他可以用他们的私人数据(地址,然后他将出售,密码,等等)骗取数百万用户。令人毛骨悚然的情景,对吧?
现在,这似乎不太真实,但是如果你让最终用户评估python脚本怎么办?您可能已经看过像gedit这样的文本编辑器或带有内置python shell的音乐播放器(Rhythmbox),为程序内部提供了接口。现在,soemone以某种方式将object
行为更改为您的计算机。另一个令人毛骨悚然的情景。
这些是我想到的例子,我真的不记得python的创建者对它的评价 - 这就是为什么我提供了进一步讨论的链接。
有点偏离主题 - 这实际上可能导致一些优秀的库(“这”意味着“允许对内置的猴子修补”)。想象一下猴子修补所有bultins,以便将它们存储在一些多处理管理器中。你几乎可以基于多处理获得java风格的多线程,并且可以以某种方式避免GIL。当然,还有许多其他原因导致这种情况不太好(例如,“多线程的幻觉不是多线程”),但我发现它对简单的日常桌面脚本很有用。