Baru-baru ini saya menggunakan memoryview untuk menjawab soalan ini.
Bytearray ialah jujukan bait boleh ubah, berbanding str dalam Python2, tetapi str tidak boleh diubah. Dalam Python3, memandangkan str ialah pengekodan unikod secara lalai, ia hanya boleh diakses oleh bait melalui bytearray.
Memoryview menyediakan antara muka akses memori bait demi bait untuk objek yang menyokong protokol penimbal[1,2]. Procotol penimbal sokongan str dan bytearray lalai. Perbandingan dua gelagat berikut: Ringkasnya, operasi penghirisan str dan bytearray akan menjana kepingan baharu str dan bytearray serta menyalin data, tetapi ia tidak akan berlaku selepas menggunakan memoryview.
Jangan gunakan memoryview
>> a = 'aaaaaa'
>> b = a[:2] # 会产生新的字符串
>> a = bytearray('aaaaaa')
>> b = a[:2] # 会产生新的bytearray
>> b[:2] = 'bb' # 对b的改动不影响a
>> a
bytearray(b'aaaaaa')
>> b
bytearray(b'bb')
Senario penggunaan saya ialah penerimaan soket dan analisis data dalam program rangkaian:
Kod penerimaan stokin sebelum menggunakan memoryview dipermudahkan seperti berikut
def read(saiz):
ret = ''
remain = size
while True:
data = sock.recv(remain)
ret += data # 这里不断会有新的str对象产生
if len(data) == remain:
break
remain -= len(data)
return ret
Selepas menggunakan meoryview, anda mengelakkan penyambungan rentetan berterusan dan penjanaan objek baharu
def read(size):
ret = memoryview(bytearray(size))
remain = size
while True:
data = sock.recv(remain)
length = len(data)
ret[size - remain: size - remain + length] = data
if len(data) == remain:
break
remain -= len(data)
return ret
Mengembalikan memoryview juga mempunyai kelebihan iaitu ia boleh menerima terus objek memoryview apabila menggunakan struct untuk membongkar parsing, yang sangat cekap (mengelakkan sejumlah besar operasi penghirisan apabila str besar dihuraikan dalam segmen).
Contohnya:
mv = memoryview('\x00\x01\x02\x00\x00\xff...')
type, len = struct.unpack('!BI', mv[:5])
...
Baru-baru ini saya menggunakan memoryview untuk menjawab soalan ini.
Bytearray ialah jujukan bait boleh ubah, berbanding str dalam Python2, tetapi str tidak boleh diubah.
Dalam Python3, memandangkan str ialah pengekodan unikod secara lalai, ia hanya boleh diakses oleh bait melalui bytearray.
Memoryview menyediakan antara muka akses memori bait demi bait untuk objek yang menyokong protokol penimbal[1,2].
Procotol penimbal sokongan str dan bytearray lalai.
Perbandingan dua gelagat berikut:
Ringkasnya, operasi penghirisan str dan bytearray akan menjana kepingan baharu str dan bytearray serta menyalin data, tetapi ia tidak akan berlaku selepas menggunakan memoryview.
Jangan gunakan memoryview
Gunakan memoryview
Senario penggunaan saya ialah penerimaan soket dan analisis data dalam program rangkaian:
Kod penerimaan stokin sebelum menggunakan memoryview dipermudahkan seperti berikut
def read(saiz):
Selepas menggunakan meoryview, anda mengelakkan penyambungan rentetan berterusan dan penjanaan objek baharu
Mengembalikan memoryview juga mempunyai kelebihan iaitu ia boleh menerima terus objek memoryview apabila menggunakan struct untuk membongkar parsing, yang sangat cekap (mengelakkan sejumlah besar operasi penghirisan apabila str besar dihuraikan dalam segmen).
Contohnya:
[1] https://jakevdp.github.io/blo...
[2] http://legacy.python.org/dev/...