Python:如何使用_setitem设置子类int的值__
我正在努力在子类int类上实现setitem 我想在该int的位片上执行操作(限制为32位)。 我知道有一个“BitVector”类可用,但这并不像人们所期望的那样有效。 例如:Python:如何使用_setitem设置子类int的值__,python,immutability,subclassing,Python,Immutability,Subclassing,我正在努力在子类int类上实现setitem 我想在该int的位片上执行操作(限制为32位)。 我知道有一个“BitVector”类可用,但这并不像人们所期望的那样有效。 例如: from BitVector import BitVector foo = BitVector(intVal = 0x87654321) print(f'[0:3] expected value = 0x1 returned value = {hex(int(foo[0:3]))}') print(f'[4:7] ex
from BitVector import BitVector
foo = BitVector(intVal = 0x87654321)
print(f'[0:3] expected value = 0x1 returned value = {hex(int(foo[0:3]))}')
print(f'[4:7] expected value = 0x2 returned value = {hex(int(foo[4:7]))}')
print(f'[24:31] expected value = 0x87 returned value = {hex(int(foo[24:31]))}')
输出为:
[0:3] expected value = 0x1 returned value = 0x4
[4:7] expected value = 0x2 returned value = 0x3
[24:31] expected value = 0x87 returned value = 0x10
0b10110010
[0] 0b0
[1] 0b1
[1:0] 0b10
[4:0] 0b10010
[7:1] 0b1011001
[8:0] 0b10110010
0xbefa55aa
[7:0] 0xaa
[15:8] 0x55
[23:16]0xfa
[31:24]0xbe
0b0 <-- expected 0x1234 !!!
BitVector的问题是位顺序颠倒(LSB为左,MSB为右),并且片中不包括结束位([0:3]返回三位,而不是四位)
所以我决定为这种操作创建自己的类。
(我颠倒了开始和结束的顺序,这样我就可以写[3:0],而不是更常见的符号[0:3])
getitem按预期工作,但我无法使用setitem设置新值
class bitfield(int):
def __str__(self):
return "%d" % int(self)
def __repr__(self):
return "bitfield(%d)" % int(self)
def __getitem__(self, sliceobj):
if not isinstance( sliceobj, slice ): return (self&(1<<sliceobj))>>sliceobj
if(sliceobj.start < sliceobj.stop): raise ValueError( "slice error: start must be >= end" )
if(sliceobj.start > 31): raise ValueError( "slice error: start > 31" )
if(sliceobj.stop > 31): raise ValueError( "slice error: end > 31" )
start = sliceobj.start
stop = sliceobj.stop
mask = (1<<((start+1) - stop))-1
val = self & ( mask << stop)
val = val>>stop
return val
def __new__(cls, value):
return int.__new__(bitfield, value)
def __setitem__(self, sliceobj, item):
self.__int__ = 0x1234
self = 0x1234
#self.__int__ = int.__new__(bitfield, 0x1234)
self = int.__new__(bitfield, 0x1234)
self = self.__new__(bitfield, 0x1234)
# test __getitem__
a = bitfield(0xB2)
print(f' {bin(a)}' )
print(f'[0] {bin(a[0 ])}')
print(f'[1] {bin(a[1 ])}')
print(f'[1:0] {bin(a[1:0])}')
print(f'[4:0] {bin(a[4:0])}')
print(f'[7:1] {bin(a[7:1])}')
print(f'[8:0] {bin(a[8:0])}')
a = bitfield(0xbefa55aa)
print(f' {hex(a)}' )
print(f'[7:0] {hex(a[ 7:0] )}')
print(f'[15:8] {hex(a[15:8] )}')
print(f'[23:16]{hex(a[23:16])}')
print(f'[31:24]{hex(a[31:24])}')
# test __setitem__
a = bitfield(0)
a[1] = 1
print(hex(a))
类位字段(int):
定义(自我):
返回“%d”%int(自)
定义报告(自我):
返回“位字段(%d)”%int(自)
def uu getitem(self,sliceobj):
如果不存在(sliceobj,slice):返回(self&(1sliceobj
if(sliceobj.start=结束”)
if(sliceobj.start>31):提升值错误(“切片错误:start>31”)
如果(切片对象停止>31):提升值错误(“切片错误:结束>31”)
start=sliceobj.start
停止
掩码=(1)
有人能给我一个如何设置新值的提示吗
不要从整数继承。整数是不可变的,不能就地更新其值
BitVector的问题是位顺序颠倒(LSB为左,MSB为右),并且片中不包括结束位([0:3]返回三位,而不是四位)
因此,您的意思是,位向量的行为类似于一组位?而不是类似于语言中的其他任何东西?如果该类不从integer继承,是否可以将其解释为integer?我在尝试打印值时遇到以下错误:TypeError:“bitfield”对象无法解释d作为整数
。事实上,python中的[0:1]与[0]是一样的,这有点奇怪,有点违反直觉,你不觉得吗?“如果类不是从integer继承的,是否可以将其解释为integer?”不可能使它与整数完全互换,尽管可以使用\uuuu int\uuuu
和\uuu index\uuuu
使它在上下文中转换为整数。“在python中,[0:1]与[0]相同的事实有点古怪和违反直觉,你不这么认为吗?”这通常是不正确的,因此不是事实,所以不是(在内置中,我认为这只发生在str
上,这有点特殊,而且不是很好)“我在尝试打印值时遇到以下错误:TypeError:'bitfield'对象不能解释为整数。
”%d
格式化程序严格要求整数。如果您的类型不是实际整数,请不要使用该整数。