Skip to main content
 首页 » 编程设计

python之如何在没有外部依赖的情况下在 Python 中实现类似 C 的 unsigned int 32

2025年05月04日8xiaohuochai

我需要一个类来保留 int 类的所有 Python 功能,但要确保其结果在 32 位整数范围内,就像在 C 编程语言中一样。该类型必须是“有毒的”——对 int 执行操作并且该类型应该导致返回该类型。正如其中一个答案所建议的那样 to my other question ,我曾经为此目的使用 numpy.uint32,但是仅仅为一个相对简单的类型添加这么大的依赖感觉太傻了。我该如何实现?到目前为止,这是我的尝试:

MODULO = 7  # will be 2**32 later on 
 
class u32: 
    def __init__(self, num = 0, base = None): 
        print(num) 
        if base is None: 
            self.int = int(num) % MODULO 
        else: 
            self.int = int(num, base) % MODULO 
    def __coerce__(self, x): 
        return None 
    def __str__(self): 
        return "<u32 instance at 0x%x, int=%d>" % (id(self), self.int) 
    def __getattr__(self, x): 
        r = getattr(self.int, x) 
        if callable(r): 
            def f(*args, **kwargs): 
                ret = r(*args, **kwargs) % MODULO 
                print("x=%s, args=%s, kwargs=%s, ret=%s" % (x, args, kwargs, ret)) 
                if x not in ['__str__', '__repr__']: 
                    return u32(ret) 
                return r(*args, **kwargs) 
            return f 
        return r 
 
u = u32(4) 
print("u/2") 
a = u * 2 
assert(isinstance(a, u32)) 
 
print("\n2/u") 
a = 2 * u 
assert(isinstance(a, u32)) 
 
print("\nu+u") 
""" 
Traceback (most recent call last): 
  File "u32.py", line 44, in <module> 
    a = u + u 
  File "u32.py", line 18, in f 
    ret = r(*args, **kwargs) % MODULO 
TypeError: unsupported operand type(s) for %: 'NotImplementedType' and 'int' 
""" 
a = u + u 
assert(isinstance(a, u32)) 

请您参考如下方法:

显然正确的方法是编写所有特殊方法(这可能很痛苦)。

否则,为你的 __getattr__ 试试这个

def __getattr__(self, x): 
    r = getattr(self.int, x) 
    if callable(r): 
        def f(*args, **kwargs): 
            if args and isinstance(args[0], u32): 
                args = (args[0].int, ) + args[1:] 
            ret = r(*args, **kwargs) 
            if ret is NotImplemented: 
                return ret 
            if x in ['__str__', '__repr__', '__cmp__', '__index__']: 
                return ret 
            ret %= MODULO 
            return u32(ret) 
        return f 
    return r 

正如 Martijn 所说,这只适用于旧式类。参见 his answer对于适用于新型类的方法。