Python、バイト配列に32ビット整数を入れる方法

私は通常このようなことをC ++で行いますが、私はPythonを使って簡単なスクリプトを書いています。私は壁にぶつかりました。

私がバイナリリストを持っていれば(あるいは何かpythonが "fread"の結果を格納していれば)。私はバッファ内の個々のバイトにアクセスすることができます:buffer [0]、buffer [1]など

新しい32ビットのファイルサイズを保持するためにバイト[8-11]を変更する必要があります(読んでください:すでにファイルサイズがあり、それを更新する必要があります)。 C + +では、私はちょうど場所へのポインタを取得し、整数を格納するキャストが、私は突然、このような何かをする方法がわかりませんでした。

どうすれば私のバッファ内の特定の場所でPythonの整数の値を保持するために4バイトを更新できますか?

編集

私は解決策からそれを理解しているようには見えないので(私は彼らが正しい軌道にいることがわかりますが)、さらに追加します。

まず第一に、私はPython 2.4を使っています(そして、大企業のサーバをアップグレードすることはできません)。以前は言及してくれなかったことを申し訳ありません。

第二に、これを超簡単にしましょう。

私は、 'myfile.binary'という5バイトの内容 '4C53535353'という16進数のバイナリファイルを持っているとします。これはファイル内に "Lと4xS"という文字が1文字だけ表示されていることに相当します。

私が行った場合:

f = open('myfile.binary', 'rb')
contents = f.read(5)

内容は(Sven Marnachの答えから)5バイトの不変の文字列を保持すべきです。

Python 2.4の機能のみを使用して、どのように 'contents'に保持されている4 Sを任意の整数値に変更できますか?私。バイトインデックスの内容[1-4]に値12345678910の32ビット整数 'myint'を含めることができるコード行を私に与えてください。

6
ありがとう、私は新しい文字列またはバイト配列を作成する場合は幸せです。同じcontnetsで変更可能なバイト配列を作成し、それの範囲[1-4]を私の整数のバイナリ表現と等しく更新するにはどうすればよいですか?
追加された 著者 John Humphreys - w00te,
文字列が不変なので内容を変更することはできません...新しい文字列を作成するか、bytearrayのような変更可能なコンテナを使用することができます。
追加された 著者 hochl,
私は以下の投稿を拡張し、Python 2.4の実際の例を含めました:-)
追加された 著者 hochl,

5 答え

あなたが必要とするのはこの機能です:

struct.pack_into(fmt, buffer, offset, v1, v2, ...)

http://docs.python.org/library/struct.html に記載されています。上の近くに。

コード例:

import struct
import ctypes

data=ctypes.create_string_buffer(10)
struct.pack_into(">i", data, 5, 0x12345678)
print list(data)

Similar posting: Python: How to pack different types of data into a string buffer using struct.pack_into

EDIT: Added a Python 2.4 compatible example:

import struct

f=open('myfile.binary', 'rb')
contents=f.read(5)
data=list(contents)
data[0:4]=struct.pack(">i", 0x12345678)
print data
9
追加された
皆のために私は、パックページと提供されているソリューションを読んで作業を進めました。私は2.5の代わりにPython 2.4を持っているので、私はたくさん足りないようです。上記の私の記事の編集で私の問題を大幅に簡略化したバージョンを提供しました。もしあなたがコード行でそれを答えることができれば、私は完全に幸せになれます:)
追加された 著者 John Humphreys - w00te,
+1。 ctypes.create_string_buffer の代わりに可変バッファを作成するために、組み込みの bytearray を使用することをお勧めします。
追加された 著者 Sven Marnach,
うーん。それは本当です、私はpack_into機能を避けただけです...恥ずかしがり屋。 2.4で何があったのか見てみましょう:)
追加された 著者 hochl,
私は今、Python 2.4でVMで試してみました。その他の異論は?
追加された 著者 hochl,
私はあなたの2.4互換バージョンが、2.6で導入された bytearray を使用できないのではないかと心配しています。
追加された 著者 Scott Griffiths,

構造モジュールをご覧ください。 pack 関数が必要です。

編集:

コード:

import struct

s = "LSSSS" # your string
s = s[0] + struct.pack('

出力:

L╙☻ЦI

struct.pack should be available in Python2.4.

あなたの番号 "12345678910"は4バイトにパックすることはできません。少し短くしました。

4
追加された
hochlの回答に関するコメントを見る
追加された 著者 John Humphreys - w00te,
答えを更新しました
追加された 著者 Andriy Tylychko,

file.read()の結果はPythonの文字列であり、不変です。達成しようとしているタスクのコンテキストによっては、問題の解決方法が異なります。

1つは 配列モジュールを使用しています: 32ビット整数の配列。この配列を変更してファイルに書き戻すことができます。

with open("filename") as f:
    f.seek(0, 2)
    size = f.tell()
    f.seek(0)
    data = array.array("i")
    assert data.itemsize == 4
    data.fromfile(f, size//4)
data[2] = new_value
# use data.tofile(g) to write the data back to a new file g
2
追加された
hochlの回答に関するコメントを見る
追加された 著者 John Humphreys - w00te,

科学計算によく使われるnumpyモジュールをインストールすることができます。

read_data = numpy.fromfile(file = id、dtype = numpy.uint32)

その後、目的の場所のデータにアクセスして変更を加えます。

2
追加された
hochlの回答に関するコメントを見る
追加された 著者 John Humphreys - w00te,

以下は、4バイトが整数に変換されたときに実際に何が起こるかを理解するためのデモンストレーションです。 あなたが番号を持っているとします:15213

Decimal: 15213
Binary: 0011 1011 0110 1101
Hex: 3 B 6 D

リトルエンディアンシステム(すなわちx86マシン)では、この数字は長さ4のバイアレイを b "\ x6d \ x3b \ x00 \ x00" または b "mとして表すことができます。 \ x00 \ x00 "を画面に表示して4バイトを整数に変換する場合、単純に基本変換を行います。この場合、

sum(n*(256**i) for i,n in enumerate(b"\x6d\x3b\x00\x00"))

これにより、結果が得られます。15213

1
追加された