先頭にデータ長が付いたstr型のデータを扱うことが多い。
こんなのだ。
cmd = '\x03\x12\x34\x56'
Cだったら、先頭のデータ長を取ってきたい場合、こうするだろう。
cmd = "\x03\x12\x34\x56";
uint8_t length = (uint8_t)cmd[0];
pythonだと、いつもこうやっている。
cmd = '\x03\x12\x34\x56'
length = struct.unpack('B', cmd[0])[0]
これが、ぱっと頭に思いつかない。。
そして、長い。
他に方法はないのだろうか?
1つ私が勘違いしていたのは、16進数でデータを突っ込んだ文字列はbytearray型だと思い込んでいたことだ。
文字列は、文字列だ。だからstr型になる。
これがッ、bytearray型だッ!
cmd = bytearray([0x03, 0x12, 0x34, 0x56])
まあ、他に記述方法があるのかもしれんが、見つけたのがこの書き方だった。
Cの書き方に近い。
この書き方の利点は、数値を取ってくることが可能なところだ。
cmd = bytearray([0x03, 0x12, 0x34, 0x56])
print 'cmd[0]=', cmd[0]
期待通り!
ただ、str型ではないので、こういうのはできない。
print 'cmd=', cmd.encode('hex')
が、これならいける。
print 'cmd=', str(cmd).encode('hex')
そうか。。。SQLiteで取ってきたBLOB型をstrして使っていたが、こういう意味だったのか・・・。
そういえば、BLOB型にINSERTとかするときも、bytearrayで囲んでいるし。
今はstrベースでやっているので、こういう感じで使うのがよさそうだ。
cmd = '\x03\x12\x34\x56'
print 'cmd=', cmd.encode('hex')
length = bytearray(cmd)[0]
cmd_byte = cmd[1: 1 + length]
print 'cmd_byte=', cmd_byte.encode('hex')
これだと、3バイト分表示されるので、これでいこう。
lengthに代入するのが「bytearray(cmd[0])」だとダメだった。
1バイト分取ってくるという意味では同じそうに見えるのだが。。。
などとごにょごにょ調べていたら、もう1つ別の方法を見つけた。
ord()だ。
length = ord(cmd[0])
こういうのを求めてたんだよ!
逆のパターンの、数値を文字列化する場合はchr()だそうだ。
今までこうやって書いていたのだけど、
%02x' % length
これでよいことになる(lengthの範囲によるけど)。
chr(length)
こう書くと、「cmd2= 02789a」となる。
cmd2 = chr(2) + chr(0x78) + chr(0x9a)
print 'cmd2=', cmd2.encode('hex')
組み込み関数は、私が求めているものが多そうなので気に掛けておかねば。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。