我想模拟无符号 4 位整数的溢出行为,如下所示:
>>> x, y = Int4(10), Int4(9)
>>> x + y
Int4(3)
>>> x * y
Int4(10)
内置 int
的继承似乎有效。是否可以在不重写像 __add__
这样的运算符方法的情况下实现 Int4
类?
最佳答案
不,子类化 int
不会在对其应用算术时自动重用该类型:
>>> class Int4(int):
... def __new__(cls, i):
... return super(Int4, cls).__new__(cls, i & 0xf)
...
>>> x, y = Int4(10), Int4(9)
>>> x + y
19
>>> type(x + y)
<type 'int'>
您必须覆盖__add__
等方法,以便在执行此操作时转换回Int4()
。
如果您只想支持类型本身(例如,不支持在此过程中转换其他数字类型),那么您可以生成其中的大部分:
from functools import wraps
class Int4(int):
def __new__(cls, i):
return super(Int4, cls).__new__(cls, i & 0xf)
def add_special_method(cls, name):
mname = '__{}__'.format(name)
@wraps(getattr(cls, mname))
def convert_to_cls(self, other):
bound_original = getattr(super(cls, self), mname)
return type(self)(bound_original(other))
setattr(cls, mname, convert_to_cls)
for m in ('add', 'sub', 'mul', 'floordiv', 'mod', 'pow',
'lshift', 'rshift', 'and', 'xor', 'or'):
add_special_method(Int4, m)
add_special_method(Int4, 'r' + m) # reverse operation
这产生的方法总是从算术特殊方法返回self
的类型;这也将允许对 Int4
进行进一步的子类化。
演示:
>>> from functools import wraps
>>> class Int4(int):
... def __new__(cls, i):
... return super(Int4, cls).__new__(cls, i & 0xf)
...
>>> def add_special_method(cls, name):
... mname = '__{}__'.format(name)
... @wraps(getattr(cls, mname))
... def convert_to_cls(self, other):
... bound_original = getattr(super(cls, self), mname)
... return type(self)(bound_original(other))
... setattr(cls, mname, convert_to_cls)
...
>>> for m in ('add', 'sub', 'mul', 'floordiv', 'mod', 'pow',
... 'lshift', 'rshift', 'and', 'xor', 'or'):
... add_special_method(Int4, m)
... add_special_method(Int4, 'r' + m) # reverse operation
...
>>> x, y = Int4(10), Int4(9)
>>> x + y
3
>>> x * y
10
关于python - 如何在 Python 3 中模拟 4 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23709429/