pythonpython-3.xslicememoryviewpython-bytearray

python slice assignment and memoryview of bytearray


Sorry if my English is bad, I speak Korean as mother tongue.

I was writing code that changes bytearray partially. And what I was trying to is to give name for memoryview of some sections of bytearray, and update bytearry with that memoryview. roughly like:

some_section_name_1 = memoryview(binary_data[section1_start:section1_end])
some_section_name_2 = memoryview(binary_data[section2_start:section2_end])

#update
some_section_name_1[:] = byte_like_object
some_section_name_2[:] = byte_like_object

but it failed. so I wrote following code to check:

section1_start, section1_end = 3, 7

binary_data = bytearray(range(8))
some_section_name_1 = memoryview(binary_data[section1_start:section1_end])
some_section_name_1[:] = bytes(range(4))
print(binary_data)

binary_data = bytearray(range(8))
whole_mv = memoryview(binary_data)
whole_mv[section1_start:section1_end] = bytes(range(4))
print(binary_data)

binary_data = bytearray(range(8))
binary_data[section1_start:section1_end] = bytes(range(4))
print(binary_data)

and then I finally recalled that slicing will do shallow copy, so slice assignment would only apply to that copied object, not the original object.

Then, will there be any way that can achieve my original purpose? to name some specific sections of bytearray and update bytearray with that name. Must it be whole bytearray | whole memoryview?


Solution

  • If I understand you correctly, you want something like:

    view = memoryview(binary_data)
    # the following slicing operations are constant time/space!
    section1 = view[section1_start:section1_end]
    section2 = view[section2_start:section2_end]
    
    some_section_name_1[:] = byte_like_object
    some_section_name_2[:] = byte_like_object
    

    You are right, once you slice the bytearray, it creates a new bytearray. you need to slice the memoryview.

    So, as an example:

    >>> binary_data = bytearray(b"foo-bar-baz")
    >>> view = memoryview(binary_data)
    >>> section1 = view[:3]
    >>> section2 = view[-3:]
    >>> binary_data
    bytearray(b'foo-bar-baz')
    >>> section1[:] = b"###"
    >>> section2[:] = b"***"
    >>> binary_data
    bytearray(b'###-bar-***')