1. はじめに
Pythonでバイナリデータやバッファを効率よく扱いたいときに便利なのが、memoryview()関数です。
この記事では、「Python|memoryview()関数の使い方」をテーマに、関数の基本的な使い方から、実務でも活用できる応用例、注意点までを解説します。
memoryview()を使うことで、データのコピーなしでバッファにアクセスできるため、パフォーマンスの最適化にも役立ちます。Python初心者〜中級者に向けて、丁寧に説明していきます。
2. memoryview()関数の基本解説と使い方
memoryviewとは?
memoryview()関数は、バイト型のオブジェクト(bytes、bytearrayなど)に対して、メモリの内容をコピーせずに読み書きする方法を提供する関数です。
通常、バイナリデータの一部を変更したり処理したりする場合、新しいオブジェクトを作成する必要がありますが、memoryviewを使えば、元データの一部を直接操作できます。
基本的な使い方
# バイト配列を用意
data = bytearray(b"hello")
# memoryviewオブジェクトを作成
mv = memoryview(data)
# 一部を変更
mv[0] = 72 # 'h' → 'H'(ASCIIコード72)
print(data)
実行結果:
bytearray(b'Hello')
このように、memoryviewを使うことで元のデータ(bytearray)が直接書き換わることがわかります。
3. よくある使い方・応用例
部分的なデータアクセス
memoryviewはスライス操作にも対応しているため、大きなデータから一部を取り出す処理に非常に便利です。
data = bytearray(b"OpenAI_GPT")
mv = memoryview(data)
# 一部をスライスして表示
print(mv[6:9].tobytes())
実行結果:
b'GPT'
NumPyの代替としての使用
軽量なバイナリ処理であれば、NumPyを使わずともmemoryviewで代用できるケースがあります。
import struct
# 整数のリストをbytearrayで作成(2バイト整数×3)
raw_data = bytearray(struct.pack("hhh", 100, 200, 300))
mv = memoryview(raw_data).cast('h') # 'h' はshort型(2バイト整数)
for i in mv:
print(i)
実行結果:
100
200
300
このように、cast()を使って型を変換しながらバイナリデータにアクセスできます。
4. 注意点・エラー対策
対応しているオブジェクトに制限がある
memoryview()はすべてのデータ型に対して使えるわけではありません。基本的には bytes
、bytearray
、array.array
など、バッファインターフェースを持つオブジェクトに限られます。
# リストでは使えない
data = [1, 2, 3]
mv = memoryview(data) # TypeError
実行結果:
TypeError: memoryview: a bytes-like object is required, not 'list'
immutable(変更不可)なオブジェクトには書き込みできない
たとえば、bytes
オブジェクトは不変(immutable)なので、memoryview経由で書き込みしようとするとエラーになります。
data = bytes(b"hello")
mv = memoryview(data)
mv[0] = 72 # 書き込み不可
実行結果:
TypeError: cannot modify read-only memory
5. まとめ
- memoryview()関数は、バイト型データへの効率的なアクセスを提供する便利な関数です。
- コピーをせずにメモリの中身を読み書きできるため、大規模データ処理やパフォーマンスが重要な場面で活躍します。
- NumPyなどの代替用途として軽量に扱いたいときにも使えます。
実務では、バイナリプロトコル解析や高速なデータ処理の場面でmemoryviewが力を発揮します。
Pythonの奥深さを感じるこの関数を、ぜひ活用してみてください。