memoryviewのドキュメントを確認する:
memoryviewオブジェクトを使用すると、Pythonコードは、コピーせずにバッファプロトコルをサポートするオブジェクトの内部データにアクセスできます。
クラスmemoryview(obj)
objを参照するmemoryviewを作成します。objはバッファプロトコルをサポートする必要があります。バッファプロトコルをサポートする組み込みオブジェクトには、bytesとbytearrayが含まれます。
次に、サンプルコードが提供されます。
>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'
引用は終わりました。では、詳しく見てみましょう。
>>> b = b'long bytes stream'
>>> b.startswith(b'long')
True
>>> v = memoryview(b)
>>> vsub = v[5:]
>>> vsub.startswith(b'bytes')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'memoryview' object has no attribute 'startswith'
>>> bytes(vsub).startswith(b'bytes')
True
>>>
だから私が上から集めたもの:
コピーせずにバッファオブジェクトの内部データを公開するmemoryviewオブジェクトを作成しますが、オブジェクトで役立つことを行うには(オブジェクトによって提供されるメソッドを呼び出すことによって)、コピーを作成する必要があります。
通常、大きなオブジェクトがある場合はmemoryview(または古いバッファオブジェクト)が必要になり、スライスも大きくなる可能性があります。大きなスライスを作成する場合、または小さなスライスを作成するが何度も作成する場合は、効率を高める必要があります。
上記のスキームでは、誰かが私がここで欠けているものを私に説明できない限り、それがどちらの状況にもどのように役立つかわかりません。
編集1:
データのチャンクが大きいので、最初から最後までデータを進めて処理したいと考えています。たとえば、文字列バッファの先頭からバッファが消費されるまでトークンを抽出します。C用語では、これはポインタをバッファ、およびポインタはバッファタイプを期待する任意の関数に渡すことができます。Pythonで同様のことをどのように行うことができますか?
人々は回避策を提案します。たとえば、多くの文字列関数と正規表現関数は、ポインタの前進をエミュレートするために使用できる位置引数を取ります。これには2つの問題があります。1つは回避策であり、欠点を克服するためにコーディングスタイルを変更する必要があります。2つ目は、すべての関数に位置引数があるわけではありません。たとえば、正規表現関数とstartswith
実行encode()
/decode()
しないです。
他の人は、データをチャンクでロードするか、最大トークンよりも大きい小さなセグメントでバッファーを処理することを提案するかもしれません。さて、私たちはこれらの可能な回避策を知っていますが、言語に合うようにコーディングスタイルを曲げようとせずに、Pythonでより自然な方法で作業することになっています-そうではありませんか?
Edit2:
コードサンプルは物事をより明確にするでしょう。これが私がやりたいことであり、memoryviewで一見できると思っていました。私が探している機能にpmview(適切なメモリビュー)を使用しましょう:
tokens = []
xlarge_str = get_string()
xlarge_str_view = pmview(xlarge_str)
while True:
token = get_token(xlarge_str_view)
if token:
xlarge_str_view = xlarge_str_view.vslice(len(token))
# vslice: view slice: default stop paramter at end of buffer
tokens.append(token)
else:
break