Python自定义数字类型:包裹数字

时间:2011-03-31 19:28:44

标签: python types

快速希望;大脑已经空白了。

是否可能/实际有一个只是一个通用数值的类(例如float,int等),当一个值变为< = 0时,它会循环到os.maxint-value,类似于unsigned C中的值?

'这完全是疯了'也是一个可以接受的答案!

'合理'使用原因;一个特定的“努力”成本评估,其中负“成本”虽然理论上很好,实际上是无效的,并且通常检查每个值,如果< = 0则翻转到maxint。

而不是所有那些可爱的额外比较,只需给出这种内在行为的成本价值。

3 个答案:

答案 0 :(得分:3)

找到答案

使用Numpy的uint类型适用于此。

import numpy.uint32
valueA=uint32(5)
valueB=uint32(-5)
assert valueA < valueB

答案 1 :(得分:0)

首先,Python通常没有maxint值,因为它的整数类型是无界的。当它超过sys.maxint时,它会变成long类型。如果你想将它作为类属性和属性,如果你想将它作为实例属性,你仍然可以通过编写描述符轻松实现你想要的东西。

答案 2 :(得分:0)

我最近写了这样的内容和blogged about it。 OP基本上已经说明了为什么要这样做的TL / DR:您可能想使用Python来模拟C或x86汇编代码的行为,在这些行为中,操作通常以2²²或以2的幂进行模运算。而且,您可能想要一种实现有限域元素的类型。以下代码可同时实现这两个功能。

我知道,花哨的元类化有点过分,但是我希望它真的很紧凑,而元类是使它保持简短的简单方法。

class wrapped(type):
    def __new__(cls, name, bases, nmspc, mod=None, bits=None, hexrep=False, signed=False):
        assert int in bases[0].__mro__
        if None not in (mod, bits) and 1 << bits != mod:
            raise ValueError('incompatible mod and bits argument.')
        mod = mod or bits and 1 << bits
        if mod:
            for op in 'add', 'and', 'floordiv', 'lshift', 'mod', 'mul', 'or', 'rshift', 'sub', 'xor':
                opname = F'__{op}__'
                nmspc[F'__r{op}__'] = nmspc[opname] = lambda self, them, op=getattr(int, opname): (
                    self.__class__(op(self, them)))
            nmspc['__rtruediv__'] = nmspc['__truediv__'] = lambda self, them, p=int.__pow__: (
                self.__class__(self * p(them, -1, mod)))
            nmspc['__pow__'] = lambda self, them, op=int.__pow__: self.__class__(op(self, them, mod))
            nmspc['__inv__'] = lambda self, op=int.__invert__: self.__class__(op(self))
            nmspc['__neg__'] = lambda self, op=int.__neg__: self.__class__(op(self))
            nmspc.update(mod=mod, signed=signed)
            if hexrep is True:
                nib, up = divmod((mod.bit_length() - 1) - 1, 4)
                nib += bool(up)
                nmspc['__repr__'] = lambda self: F'{self:#0{nib}x}'
        return type.__new__(cls, name, bases, nmspc)

    def __call__(cls, value=0, *args, **kwargs):
        if isinstance(value, int):
            value = value % cls.mod
            if cls.signed and (value & (cls.mod >> 1)):
                value -= cls.mod
            return type.__call__(cls, value)
        return cls(int(value, *args, **kwargs))


class wrap(int, metaclass=wrapped):
    pass

您将按以下方式使用它:

In [2]: class uint32(wrap, mod=(1 << 32), hexrep=True): pass

In [3]: a = uint32(0xC0C4C01A)

In [4]: a
Out[4]: 0x0C0C4C01A

In [5]: a ** 0x00F
Out[5]: 0x02A028000

或者,如果您不喜欢十六进制表示,则不要为新的整数类型将hexrep设置为True