Python:如何使用_setitem设置子类int的值__

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

我正在努力在子类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] 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
格式化程序严格要求整数。如果您的类型不是实际整数,请不要使用该整数。