2

私はPythonが初めて(1日)なので、私の質問はばかげているかもしれません。私はすでにここを見てきましたが、答えが見つかりません。

ランダムなサイズのランダムなオフセットで配列の内容を変更する必要があります。変更できない USB デバイスの DDL をインターフェイスする Python API があります。このような関数があります:

def read_device(in_array):
    # The DLL accesses the USB device, reads it into in_array of type array('B')
    # in_array can be an int (the function will create an array with the int 
    # size and return it), or can be an array or, can be a tuple (array, int)

MY コードでは、たとえば 64 バイトの配列を作成し、32 バイト目から 16 バイトを読み取りたいとします。Cでは&my_64_array[31]read_device関数に与えます。Python では、与えられた場合:

read_device(my_64_array[31:31+16])

in_array は、指定されたサブセットのコピーへの参照であるため、my_64_array変更されていないようです。

私に何ができる ?後で分割my_64_arrayして再結合する必要がありますか??

4

3 に答える 3

1

APIコードを更新および/または変更できない方法を見てください。最善の方法は、関数に小さな一時配列を渡し、関数呼び出しの後に既存の 64 バイト配列に割り当てることです。

したがって、API 呼び出しの正確な詳細がわからない場合は、次のようになります。

the_64_array[31:31+16] = read_device(16)
于 2012-09-20T10:06:14.800 に答える
0

リストサブセットを読み取るときは、そのリストの引数を__getitem__使用して呼び出しています。slice(x, y)あなたの場合、これらのステートメントは同じです:

my_64_array[31:31+16]
my_64_array.__getitem__(slice(31, 31+16))

これは__getitem__、サブクラスで関数をオーバーライドして、異なる動作を取得できることを意味します。

を使用して同じサブセットを設定することもできますa[1:3] = [1,2,3]。その場合は、a.__setitem__(slice(1, 3), [1,2,3])

だから私はこれらのいずれかを提案します:

  • の結果を渡す代わりに、リスト(my_64_array)とsliceオブジェクトをread_deviceに渡し__getitem__ます。その後、必要なデータを読み取り、対応するオフセットを設定できます。サブクラス化はありません。これは、読みやすさと開発のしやすさの点でおそらく最良の解決策です。
  • リストをサブクラス化し、親参照を使用してそのサブクラスのインスタンスをオーバーライド__getitem____setitem__て返します。次に、リストのすべての変更メソッドまたは読み取りメソッドを変更して、代わりに親リストを参照します。Pythonを初めて使用する場合、これは少し注意が必要かもしれませんが、基本的には、Pythonリストのプロパティが主にlistインスタンス内のメソッドによって定義されることを利用します。これは、参照を作成できるため、パフォーマンスの点でおそらく優れています。
  • 結果のリストを返し、そのリストのサイズが等しい場合read_deviceは、次のように実行できます。a[x:y] = read_device(a[x:y])
于 2012-09-20T09:27:20.957 に答える
0

まさにあなたが言うように、関数にスライスを入力すると、スライスの参照コピーが作成されます。

後で追加するための2つの可能な方法(read_device関連するスライスが返されると仮定):

my_64_array = my_64_array[:32] + read_device(my_64_array[31:31+16]) + my_64_array[31+16:]
# equivalently, but around 33% faster for even small arrays (length 10), 3 times faster for (length 50)...
my_64_array[31:31+16] = read_device(my_64_array[31:31+16])

ですから、後者を使うべきだと思います。

それが変更可能な関数である場合(ただし、この場合はそうではありません!)、関数の引数を変更することができます(1つは配列全体です)。

def read_device(the_64_array, start=31, end=47):
   # some code
   the_64_array[start:end] = ... #modifies `in_array` in place

read_device(my_64_array)またはを呼び出しますread(my_64_array, 31, 31+16)

于 2012-09-20T09:28:36.323 に答える