我想模拟无符号4位整数的溢出行为,如下所示:
>>> x, y = Int4(10), Int4(9)
>>> x + y
Int4(3)
>>> x * y
Int4(10)
Run Code Online (Sandbox Code Playgroud)
内置的继承int似乎有效.是否可以在Int4不重写操作符方法的情况下实现类__add__?
不,子类化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'>
Run Code Online (Sandbox Code Playgroud)
当你这样做时,你必须重写__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
Run Code Online (Sandbox Code Playgroud)
这样生成的方法总是返回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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1976 次 |
| 最近记录: |