Для чего нужен тип буфера Python?

136

В bufferPython есть тип, но я не знаю, как его использовать.

В документации по Python описание:

buffer(object[, offset[, size]])

Аргумент объекта должен быть объектом, который поддерживает интерфейс вызова буфера (например, строки, массивы и буферы). Будет создан новый объект буфера, который ссылается на аргумент объекта. Буферный объект будет срезом от начала объекта (или от указанного смещения). Срез будет продолжаться до конца объекта (или будет иметь длину, заданную аргументом размера).

Сатору
источник

Ответы:

145

Пример использования:

>>> s = 'Hello world'
>>> t = buffer(s, 6, 5)
>>> t
<read-only buffer for 0x10064a4b0, size 5, offset 6 at 0x100634ab0>
>>> print t
world

Буфер в этом случае представляет собой подстроку, начиная с позиции 6 длиной 5, и он не занимает дополнительное место для хранения - он ссылается на фрагмент строки.

Это не очень полезно для таких коротких строк, но это может быть необходимо при использовании больших объемов данных. Этот пример использует изменчивый bytearray:

>>> s = bytearray(1000000)   # a million zeroed bytes
>>> t = buffer(s, 1)         # slice cuts off the first byte
>>> s[1] = 5                 # set the second element in s
>>> t[0]                     # which is now also the first element in t!
'\x05'

Это может быть очень полезно, если вы хотите иметь более одного представления данных и не хотите (или не можете) хранить несколько копий в памяти.

Обратите внимание, что bufferон был заменен лучшим именем memoryviewв Python 3, хотя вы можете использовать любой из них в Python 2.7.

Также обратите внимание, что вы не можете реализовать интерфейс буфера для своих собственных объектов, не углубляясь в C API, т.е. вы не можете сделать это на чистом Python.

Скотт Гриффитс
источник
Спасибо за ваше объяснение. Но я все еще не совсем понимаю, в чем разница между буферизацией и простой нарезкой. Использование s[6:11]не требует дополнительного места для хранения, я не прав?
Сатору
9
В целом, фрагмент займет дополнительное место, так что да s[6:11]будет копия. Если вы установите t = s[6:11]и затем del s, это освобождает память, которая была занята s, доказывая, что tбыло скопировано. (Чтобы увидеть это, вам нужно больше sи отслеживать использование памяти Python). Однако гораздо эффективнее сделать копию, если данных не так много.
Скотт Гриффитс
1
Большое спасибо :) Кстати, не могли бы вы сказать мне, какой инструмент я могу использовать для отслеживания использования памяти Python?
Сатору
Для использования памяти см. Например, stackoverflow.com/questions/110259 . Иногда проще всего наблюдать за использованием Python в диспетчере задач / Activity Monitor / top.
Скотт Гриффитс
13
Для новичков Python, таких как я: буфер - это просмотр памяти в Python 3
Дирк Бестер
25

Я думаю, что буферы, например, полезны при взаимодействии Python с нативными библиотеками. (Гвидо ван Россум объясняет bufferв этом посте ).

Например, numpy, похоже, использует буфер для эффективного хранения данных:

import numpy
a = numpy.ndarray(1000000)

a.dataявляется:

<read-write buffer for 0x1d7b410, size 8000000, offset 0 at 0x1e353b0>
Андре Хольцнер
источник