您的Python 2解决方案依赖于 旧式类的 行为。如果使类继承自Python 2,则Python 2代码将以与Python3相同的方式失败
object:
class U32(object):
这是因为对于新 类 ,将在 类型 而不是对象本身上查找特殊方法。此行为更改修复了旧模型的一些极端情况。
实际上,这意味着像这样的方法
__div__将直接在
U32自身上查找,而不是在的 实例
上作为属性
U32,并且
__getattr__不会查询该挂钩。
不幸的是,特殊的方法也查找 绕过
任何
__getattr__或
__getattribute__挂钩。请参阅有关特殊方法查找的文档:
除了出于正确性的考虑绕过任何实例属性之外,隐式特殊方法查找通常还绕过该
__getattribute__()方法,甚至对象的元类也是如此:[…]
__getattribute__()以这种方式绕过机器为解释器内的速度优化提供了很大的空间,但以牺牲一些特殊方法的灵活性为代价(特殊方法必须在类对象本身上设置,以便由解释器一致地调用)
。
那么,您唯一的选择是在类上动态设置所有特殊方法。一个类装饰器可以在这里做得很好:
def _build_delegate(name, attr, cls, type_): def f(*args, **kwargs): args = tuple(a if not isinstance(a, cls) else a.int_ for a in args) ret = attr(*args, **kwargs) if not isinstance(ret, type_) or name == '__hash__': return ret return cls(ret) return fdef delegated_special_methods(type_): def decorator(cls): for name, value in vars(type_).items(): if (name[:2], name[-2:]) != ('__', '__') or not callable(value): continue if hasattr(cls, name) and not name in ('__repr__', '__hash__'): continue setattr(cls, name, _build_delegate(name, value, cls, type_)) return cls return decorator@delegated_special_methods(int)class U32(object): def __init__(self, num=0, base=None): """Creates the U32 object. Args: num: the integer/string to use as the initial state base: the base of the integer use if the num given was a string """ if base is None: self.int_ = int(num) % 2**32 else: self.int_ = int(num, base) % 2**32 def __coerce__(self, ignored): return None def __str__(self): return "<U32 instance at 0x%x, int=%d>" % (id(self), self.int_)我更新了代理功能以正确处理多个参数,并在返回时自动强制返回到您的自定义类
int。



