2016-03-08 2 views
5

Имеет ли преобразование из изменчивого типа bytearray в не изменяемый тип bytes? Есть ли связанные с этим затраты или интерпретатор просто рассматривает его как неизменяемую последовательность байтов, например, отличая char* до const char* const в C++?Преобразуется ли преобразование из bytearray в байты в копию?

ba = bytearray() 
ba.extend("some big long string".encode('utf-8')) 

# Is this conversion free or expensive? 
write_bytes(bytes(ba)) 

отличаются ли это между Python 3, где bytes является его собственный тип и Python 2.7, где bytes просто псевдоним для str?

+0

Все операции включают * некоторые * расходы. Вы можете посмотреть источник, или вы можете использовать временные тесты, чтобы узнать, будет ли время линейно увеличиваться с размером проблемы (как это было бы, если бы была сделана копия). –

+0

Я уверен, что преобразование 'bytearray' в' bytes' берет копию. Это связано с тем, что если новые «байты» указывают на тот же базовый массив, что и «bytearray», тогда он не будет действительно неизменным. – Nayuki

+1

Обратите внимание, что если вы хотите просмотреть содержимое 'bytearray' без создания копии, вы можете использовать' memoryview' для этой цели. Предостережение заключается в том, что изменения в данных 'bytearray' изменят данные в' memoryview' и что 'bytearray' не может быть изменен (без' append', 'pop' s, изменение размеров срезов и т. Д.) Для пока существуют все экспортированные буферы (из которых 'memoryview' является наиболее распространенным типом, созданным в коде уровня Python). – ShadowRanger

ответ

11

Новая копия создается, буфер не разделяется между bytesarray и нового объекта bytes, либо в Python 2 или 3.

Вы не могли бы поделиться, как объект bytesarray еще можно ссылаться в другом месте и изменить значение.

Для получения дополнительной информации см. bytesobject.c source code, где buffer protocol используется для создания прямой копии данных (через PyBuffer_ToContiguous()).

7

Martjin is right. Я просто хотел поддержать этот ответ с источником cpython.

Глядя на источник в байтах here, первый bytes_new называется, который будет вызывать PyBytes_FromObject, который будет вызывать _PyBytes_FromBuffer, который создает новый объект байт и вызывает PyBuffer_ToContiguous (определенный here). Это вызывает buffer_to_contiguous, который является функцией копирования памяти. Комментарий к функции:

Скопируйте src в смежное представление. порядок является одним из «C», «F» (Fortran) или «A» (любой). Предположения: src имеет информацию PyBUF_FULL, src-> ndim> = 1, len (mem) == src-> len.

Таким образом, вызов байтов с аргументом bytearray будет копировать данные.