Python:如何使用__setitem __

问题描述

我正在努力在子类int类上实现 setitem

我想对该int的位片(限于32bit)执行操作。 我知道有一个'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

BitVector的问题在于,位顺序相反(LSB左,MSB右),并且结束位不包括在切片中([0:3]返回三位而不是四位)。 / p>

因此,我决定为此类操作创建自己的类。 (我颠倒了开始和结束的顺序,以便我写[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))

输出为:

       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 !!!

有人可以提示我如何设置新值吗?

解决方法

有人可以提示我如何设置新值吗?

不要从int继承。整数是不可变的,您不能就地更新它们的值。

BitVector的问题在于,位顺序相反(LSB左,MSB右),并且结束位不包括在切片中([0:3]返回三位而不是四位)。 / p>

那么您是说位向量的行为就像sequence位?而不是在语言上基本没有其他表现?