Skip to main content
 首页 » 编程设计

python之如何在 Python 3 中模拟 4 位整数

2025年05月04日14lvdongjie

我想模拟无符号 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