__getitem__: неподдерживаемые типы операндов для +: 'slice' и 'int'

Я использую реализацию циркулярного буфера из этого ответа. Большую часть времени работает нормально. После 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__()

person Ben    schedule 21.05.2019    source источник


Ответы (1)


Очевидно, я не понимаю метод getitem, этот ответ объяснил его примерами: Python: Реализация нарезки в __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])
person Ben    schedule 23.05.2019