Python「內建函數」(built-in functions)就是不用 import,隨時可以直接呼叫的函數,像 print()、len()、range() 這些,都算。
memoryview():記憶體視圖
語法:
memoryview(bytes或bytearray物件)memoryview 讓你不用複製資料,就能存取 bytes 或 bytearray 的內部記憶體。處理大量二進位資料時可以省記憶體、提升效能:data = bytearray(b'Hello World')
mv = memoryview(data)
print(mv[0]) # 72(H 的 ASCII)
print(mv[6:11]) # <memory at 0x...>
print(bytes(mv[6:11])) # b'World'重點:用切片操作不會複製資料,而是建立一個「視窗」指向同一塊記憶體:
data = bytearray(b'ABCDEF')
mv = memoryview(data)
# 切片不複製,指向同一塊記憶體
slice_mv = mv[2:5] # 對應 'CDE'
# 透過 memoryview 修改,原始資料也會改
slice_mv[0] = ord('X') # 把 C 改成 X
print(data) # bytearray(b'ABXDEF') ← 原始資料被改了!對比一般切片(會複製資料):
data = bytearray(b'ABCDEF')
# 一般切片:複製資料
copy = data[2:5]
copy[0] = ord('X')
print(data) # bytearray(b'ABCDEF') ← 原始沒改
# memoryview 切片:不複製
mv = memoryview(data)
mv_slice = mv[2:5]
mv_slice[0] = ord('X')
print(data) # bytearray(b'ABXDEF') ← 原始被改了memoryview 的一些常用屬性:
data = bytearray(b'Hello')
mv = memoryview(data)
print(len(mv)) # 5
print(mv.readonly) # False(因為是 bytearray)
print(mv.format) # 'B'(unsigned byte)
print(mv.itemsize) # 1(每個元素 1 byte)
print(list(mv)) # [72, 101, 108, 108, 111]
# bytes 的 memoryview 是唯讀的
b = b'Hello'
mv2 = memoryview(b)
print(mv2.readonly) # True
# mv2[0] = 74 # TypeError: 不能修改!小小綜合例子
# 用 memoryview 高效處理大量資料
import time
# 建立一個大的 bytearray(1MB)
size = 1024 * 1024
data = bytearray(size)
# 方法一:用一般切片(會複製)
start = time.time()
for i in range(100):
chunk = data[0:size//2] # 複製一半的資料
elapsed1 = time.time() - start
# 方法二:用 memoryview(不複製)
start = time.time()
mv = memoryview(data)
for i in range(100):
chunk = mv[0:size//2] # 不複製,只建立視圖
elapsed2 = time.time() - start
print(f"一般切片:{elapsed1:.4f} 秒")
print(f"memoryview:{elapsed2:.4f} 秒")
print(f"memoryview 快了 {elapsed1/elapsed2:.1f} 倍")