__getitem__:+:'slice'和'int'不支持的操作数类型[重复]

Posted

技术标签:

【中文标题】__getitem__:+:\'slice\'和\'int\'不支持的操作数类型[重复]【英文标题】:__getitem__: unsupported operand type(s) for +:'slice' and 'int' [duplicate]__getitem__:+:'slice'和'int'不支持的操作数类型[重复] 【发布时间】:2019-10-07 10:01:12 【问题描述】:

我正在使用来自this answer 的循环缓冲区实现。大多数时候它工作正常。运行 4 天后,出现以下错误。

File ..., line ... in __getitem__
    return(self._data[(key+self.index) % self.size])
TypeError: unsupported operand type(s) for +:'slice' and 'int' 

有问题的代码来自上面的链接:

def __getitem__(self, key):
    """Get element by index, relative to the current index"""
    if len(self._data) == self.size:
        return(self._data[(key + self.index) % self.size])
    else:
        return(self._data[key])

我不确定错误的确切含义。有人能解释一下吗?


self._data 是该循环缓冲区类的内部列表。列表内容由以下代码 (cbuffer::CircularList) 分配:

if isinstance(rr, rrm.ReadHoldingRegistersResponse):
    self.cbuffer.append([ts, (bw_task.sta, bw_task.start, bw_task.length), rr.registers])

导致错误的相关代码如下:

block_buffer = list(block_buffer)
if len(block_buffer) > 0:
    table_data = self.process_rawdata_block(block_buffer, bw_task)
    # do db operation
    if len(table_data) > 0:
        self.save_to_db(table_data)
    else:
        print("DataMgr.loop.save_to_db: WARNING: empty table_data:", 
        "table_data=", table_data, "while block_buffer=", block_buffer, 
        "bw_task=", bw_task, "wkr.cbuff.length=", len(wkr.cbuffer))
else:
    print("wkr.cbuff.length=", len(wkr.cbuffer))
    if len(wkr.cbuffer) > 0:
        print("wkr.cbuff=", wkr.cbuffer[0:10])  # <---- Throw error in cbuffer.__getitem__()

【问题讨论】:

【参考方案1】:

显然,我对 getitem 方法不了解,这个答案用例子解释了它:Python: Implementing slicing in __getitem__

修复也很简单:

def __getitem__(self, key):
    """Get element by index, relative to the current index"""
    if len(self._data) == self.size:
        if isinstance(key, slice):
            return(self._data[(idx + self.index) % self.size] for idx in range(*key.indices(len(self._data))))
        return(self._data[(key + self.index) % self.size])
    else:
        if isinstance(key, slice):
            return(self._data[idx] for idx in range(*key.indices(len(self._data))))
        return(self._data[key])

【讨论】:

以上是关于__getitem__:+:'slice'和'int'不支持的操作数类型[重复]的主要内容,如果未能解决你的问题,请参考以下文章

python日记_切片

slice()函数创建一个slice对象

Python for循环与__getitem__的关系记录

python切片详解

就地自定义对象使用 __getitem__ python 3.5 与 python 3.6 解包不同的行为

字符串的内置方法(常用) 和 解码与编码