我需要创建一个类似于C语言的变量。 我需要范围为0-255的字节或无符号字符。 这个变量应该溢出,这意味着......
myVar = 255
myVar += 1
print myVar #!!myVar = 0!!
答案 0 :(得分:8)
我在这里看到很多好的答案。但是,如果您想要创建自己的类型,可以查看Python Data model documentation。它解释了如何创建具有自定义行为的类,例如emulating numeric types。
使用此信息,您可以创建一个类似的类:
class Num:
def __init__(self, n):
self.n = (n % 256)
def __repr__(self):
return repr(self.n)
def __add__(self, other):
return Num(self.n+int(other))
# transform ourselves into an int, so
# int-expecting methods can use us
def __int__(self):
return self.n
然后你可以这样做:
>>> a = Num(100)
>>> print a
100
>>> b = a + 50
>>> print b
150
>>> c = Num(200)
>>> d = a + c
>>> print d
44
我意识到您可能希望支持比我在Num
中显示的更多操作,但是从这个示例和文档中,应该非常清楚如何添加它们。
答案 1 :(得分:5)
您必须myVar &= 0xFF
确保其保持在0-255范围内。
您通常可以根据需要对数字执行尽可能多的操作,只要在打印前屏蔽它,发送到用C编写的方法,或者需要它在8位范围内的任何操作。
答案 2 :(得分:5)
ctypes
模块包含您需要的功能,尽管是一种难以使用的形式。例如:
>>> import ctypes
>>> ctypes.c_ubyte(255)
c_ubyte(255)
>>> ctypes.c_ubyte(255 + 1)
c_ubyte(0)
这也适用于签名类型:
>>> ctypes.c_byte(127 + 1)
c_byte(-128)
您可以取消装入对象以获取基元 int喜欢这样:
>>> ctypes.c_byte(127 + 1).value
-128
答案 3 :(得分:1)
结合Blair的优秀答案和我之前的答案(因为它们都是截然不同的解决方案,你可能比另一个更喜欢:
导入ctypes
class CInt:
def __init__(self, ctype, n):
self.ctype = ctype
self.n = ctype(n)
def __repr__(self):
return repr(self.n.value)
def __add__(self, other):
return CInt(self.ctype, self.n.value + int(other))
# transform ourselves into an int, so
# int-expecting methods can use us
def __int__(self):
return self.n.value
它类似于Blair,除了你可以传递你想在构造函数中使用的ctypes类型构造函数:
>>> n = CInt(ctypes.c_byte, 127)
>>> n + 1
-128
答案 4 :(得分:1)
要扩展@Blair Conrad's answer:替代实现可以继承int
并覆盖所需的方法:
class Byte(int):
_all = None # cache
__slots__ = ()
def __new__(cls, value):
if Byte._all is None:
Byte._all = [int.__new__(cls, i) for i in xrange(256)]
return Byte._all[value % 256]
def __iadd__(self, other):
return self + Byte(other)
def __isub__(self, other):
return self - Byte(other)
def __add__(self, other):
if isinstance(other, Byte):
return Byte(int(self) + other)
return int(self) + other
def __sub__(self, other):
if isinstance(other, Byte):
return Byte(int(self) - other)
return int(self) - other
def __neg__(self):
return Byte(-int(self))
def __repr__(self):
return "Byte(%d)" % self
示例:
>>> myvar = Byte(255)
>>> myvar
Byte(255)
>>> myvar += 1
>>> myvar
Byte(0)
>>> myvar -= 1
>>> myvar
Byte(255)
>>> -myvar
Byte(1)
>>> myvar.i = 1
Traceback (most recent call last):
...
AttributeError: 'Byte' object has no attribute 'i'
>>> from itertools import permutations
>>> for a,b in permutations((Byte(1), Byte(-1), 1), 2):
... print "%r + %r = %r" % (a,b, a+b)
... print "%r - %r = %r" % (a,b, a-b)
Byte(1) + Byte(255) = Byte(0)
Byte(1) - Byte(255) = Byte(2)
Byte(1) + 1 = 2
Byte(1) - 1 = 0
Byte(255) + Byte(1) = Byte(0)
Byte(255) - Byte(1) = Byte(254)
Byte(255) + 1 = 256
Byte(255) - 1 = 254
1 + Byte(1) = 2
1 - Byte(1) = 0
1 + Byte(255) = 256
1 - Byte(255) = -254
>>> id(Byte(255)) == id(Byte(1)+Byte(254))
True