Учитывая memoryview
, который является частью его данных поддержки, как я могу получить slice
, который memoryview
представляет в настоящее время?
Например, скажем, мне дано это memoryview
, но не знаете, как он был нарезан до этой точки:
m = memoryview(b'This is a test')[1:5]
Как мне получить slice(1, 5, None)
из m
?Если бы такая вещь существовала и называлась get_memoryview_slice
, то я бы ожидал, что memoryview(m.obj)[get_memoryview_slice(m)]
создаст новый фрагмент памяти, идентичный m
(указывающий на ту же область в памяти).
Просмотр через Документы Python для memoryview
, я вижу, как я могу получить все, кроме начального индекса (1
в приведенном выше примере; 5
выводится из shape
и None
выводится из strides
).
Документация C раскрывает нечто более многообещающее.А именно, PyMemoryView_GET_BUFFER
и PyMemoryView_GET_BASE
выглядят так, как будто их можно использовать для поиска начального индекса.PyMemoryView_GET_BUFFER(m)->buf
- указатель на начало данных, на которые указывает просмотр памяти.Я подозреваю, что это будет не так просто, как PyMemoryView_GET_BASE(m) - PyMemoryView_GET_BUFFER(m)->buf
, поскольку первый из них выглядит как объект Python (все, что соответствует буферу, так что это может быть bytearray
, bytes
и т. Д.).Но, похоже, это путь к этому.
К сожалению, я считаю, что такой подход, по крайней мере, будет зависеть от cpython и, вероятно, потребует написания расширения на Си.Я бы предпочел избегать их обоих.
В настоящее время я пишу через реализацию memoryview
( memoryobject.h , memoryview.c ).Я еще не нашел ни одного места, которое могло бы обеспечить косвенный способ получения смещения (например, repr
использует адрес memoryview
, а не базовый буфер).
Для моего конкретного использованияслучай, это просто для аннотирования исключений с более полезными метаданными (например, «была эта ошибка при смещении байта 4242» вместо просто «была эта ошибка»).Итак, я в порядке с чем-то хакерским или хитрым, но, очевидно, было бы неплохо, если бы был санкционированный способ сделать это.В идеале, я также избегаю оборачивать memoryview
в свой собственный объект и переопределять все его методы для отслеживания срезов.